练习题目8

1.编写函数:
unsigned int reverse_bit(unsigned int value);
这个函数的返回值value的二进制位模式从左到右翻转后的值。
如:
在32位机器上25这个值包含下列各位:
00000000000000000000000000011001
翻转后:(2550136832)
10011000000000000000000000000000
程序结果返回:
2550136832
思路:将value和1相与,可以得到value的最低位。变量p初始化为0,将value最低位和p相或,可以将value的最低位给到p的最低位。循环value的位数次即32次,循环中执行以上操作,来完成每一位的翻转。注意的是:value第一次和1相与后,之后每次都右移一位,因而依次获得value的每一位。p每次和得到value的最低位相或之前都要先将p左移一位,这样,value的低位在p上就向高位依此移动。
代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
unsigned int reverse_bit(unsigned int value){
 int i = 0;
 int p = 0;
 for (i = 0; i < 32; ++i){
  p <<= 1;
  p = p|(value & 1);
  value >>= 1;
 }
 return p;
}
 int main(void){
  int value = 0;
  scanf("%d", &value);
  unsigned int result = reverse_bit(value);
  printf("%u\n", result);
  system("pause");
  return 0;
 }

在这里插入图片描述
2.不使用(a+b)/2这种方式,求两个数的平均值。
思路:为了防止数字太大超出范围,先计算加法而导致计算错误。所以先用减法算出两数之差,再将1/2差值加上较小的减数或者较大减数减去1/2差值就是平均值。
在这里插入图片描述
代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
double Add(int a, int b){
 double result = 0.0;
 if (a > b){
  result = (a - b) / 2 + b;
 }
 else{
  result = (b - a) / 2 + a;
 }
 return result;
}
 int main(void){
  int a = 0;
  int b = 0;
  scanf("%d %d", &a, &b);
  double result = Add(a, b);
  printf("%f\n", result);
  system("pause");
  return 0;
 }

在这里插入图片描述
3.编程实现:
一组数据中只有一个数字出现了一次。其他所有数字都是成对出现的。
请找出这个数字。(使用位运算)
思路:可知两两相等的数字异或结果为0,所以让所有数字进行异或,这样相同数对抵消后就只剩出现一次的数字了。
代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#define Max 100
int Func(int arr[],int size){
 int i = 0, j = 0;
 for (; i < size; ++i){
  scanf("%d", &arr[i]);
 }
 for (j = 1; j < size; ++j){
  arr[0] ^= arr[j];
 }
 return arr[0];
}
int main(void){
 int arr[Max] = { 0 };
 int n = 0;
 scanf("%d", &n);
 Func(arr, n);
 printf("%d\n", arr[0]);
 system("pause");
 return 0;
}

在这里插入图片描述
4.
有一个字符数组的内容为:“student a am i”,
请你将数组的内容改为"i am a student".
要求:
不能使用库函数。
只能开辟有限个空间(空间个数和字符串的长度无关)。
student a am i
i ma a tneduts
i am a student
思路:begin和end分别代表一个单词的首、末字母,初始化为0.先将整句话中的每个单词反转,循环字符串的长度次。只要不遇到空格或者结束标志“\0”,就给end++,直至遇到空格,这时是第一个单词的末尾,调用函数,首字母为下标0的内容,末尾字母为下标为end-1的内容。接下来依此寻找下几个单词直至遇到结束标志“\0”,寻找之前,先将begin的值赋为end++即为下一个单词的首字母位置。每个单词反转后,进行整个字符串的反转。
代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<String.h>
//反转arr[]中下标从begin到end的内容
void Reverseword(char arr[],int begin,int end){
 while (begin < end){
  int temp = 0;
  temp = arr[begin];
  arr[begin] = arr[end];
  arr[end] = temp;
  ++begin;
  --end;
 }
}
void Reverse(char ch[], int length){
 int begin = 0;
 int end = 0;
 int i = 0;
 //反转每个单词
 while (i < length+1){
  if (ch[end] == ' ' || ch[end] == '\0'){
   Reverseword(ch, begin, end - 1);
   begin = ++end;
  }
  else{
   ++end;
  }
  ++i;
 }
 //整句反转
 Reverseword(ch, 0, length - 1);
}
 int main(void){
  char ch[] ="student a am i";
  int len = strlen(ch);
  printf("翻转前:%s", ch);
  Reverse(ch,len);
  printf("\n");
  printf("翻转后:%s\n", ch);
  system("pause");
  return 0;
 }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_44779696/article/details/88997688