Program.13(数字二进制翻转,求平均值,求一组数据中单个出现的数字,使用指针对字符串进行复杂翻转)

1.编写函数: 
unsigned int reverse_bit(unsigned int value); 
这个函数的返回值是value的二进制位模式从左到右翻转后的值。 


如: 
在32位机器上25这个值包含下列各位: 
00000000000000000000000000011001 
翻转后:(2550136832) 
10011000000000000000000000000000 
程序结果返回: 
2550136832 

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
unsigned int  reverse_bit(unsigned int value)
{
	int j = 0;
	int tmp = 0;
	for (j = 0; j < 32;j++)
	{
		 tmp=tmp+((value >> j) & 1)*pow(2,31-j);//右移之后进行乘以2^(31-j).
	}
	return tmp;
}
int main()
{
	int value = 0;
	printf("请输入: ");
	scanf("%d", &value);
	int ret = 0;
	ret =reverse_bit(value);
	printf("%u\n",ret);//%u打印无符号十进制整数
	system("pause");
	return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
unsigned int  reverse_bit(unsigned int value)
{
	int j = 0;
	int tmp = 0;
	for (j = 0; j < 32; j++)
	{
		tmp+= ((value >> j) & 1)<<(31-j);//先得到这个数每一位(即通过右移&1),再从得到的二进制最低位依次左移31-j
	}
	return tmp;
}
int main()
{
	int value = 0;
	printf("请输入: ");
	scanf("%d", &value);
	printf("%u\n", reverse_bit(value));//%u打印无符号十进制整数
	system("pause");
	return 0;
}


2.不使用(a+b)/2这种方式,求两个数的平均值。 

//1
#include <stdio.h>
#include <stdlib.h>
int main()
{
	double a = 25.0;
	double b = 14.0;
	double avg= b+(a-b) / 2.0;
	printf("%f", avg);
	system("pause");
	return 0;
}
//2
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 10;
	int b = 10;
	int avg1 = 0;
	int avg2 = 0;
	avg2 = (b + ((a - b)>>1));//  << >> 运算符操作数均为整数
	avg1 = (a&b) + (a ^ b)/2;//avg1 = (a&b) + (a ^ b)>>;
	printf("avg2= %d\n", avg2);
	printf("avg1= %d\n", avg1);
	system("pause");
	return 0;
}

方法1,2各有优缺点:方法2由于受到操作符限制只能进行整数运算,方法1就可以实现小数之间的avg计算.

3.编程实现: 
一组数据中只有一个数字出现了一次。 
其他所有数字都是成对出现的。 
请找出这个数字。(使用位运算) 

#include <stdio.h>
#include <stdlib.h>
int main()
{
    int arr[9] = { 1, 2, 3, 4, 4, 3, 1, 2, 5 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int i = 0;
    int ret = 0;
    for (i = 0; i < sz; i++)
    {
        ret = ret ^ (arr[i]);
    }
    printf("%d\n", ret);
    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      每个空格处字符串逆置
先将字符串整个逆置,形成i ma a tneduts,
然后利用指针,如果指针指向空白符,说明前边的内容为一个单词然后逆置,
直到指针指向的内容为'\0'的前一项位置,此时字符串则为i am a student.

#include <stdio.h>
#include <stdlib.h>
int my_strlen(char*arr)//定义求字符串长度函数
{
	if (arr == NULL)
	{
		return 0;
	}
	int cout = 0;
	while ('\0' != *arr)
	{
		cout++;
		arr++;
	}
	return cout;	
}
void my_reverse(char *left, char *right) //定义具有逆置字符功能的函数
{
	char tmp = NULL;
	while (left < right)
	{
		tmp = *left;
		*left = *right;
		*right = tmp;
		left++;
		right--;
	}
}
void reverse_str(char arr[],int sz)    //定义逆置字符串的函数
{
	char *start = arr;
	char *end = arr + sz - 1;  
	char *curr = NULL;
	if ((arr == NULL) || (arr[0] == '\0')) //如果指针为空或者首元素为字符串结束符
	{
		return;            //字符串为空,直接结束程序
	}
	my_reverse(start, end);
	while (*arr)              //不为NULL,‘\0’的情况
	{
		curr = arr;
		while ((*arr != '\0') && (*arr != ' ')) //元素不为\0和空白符,说明一个单词还未读取完毕
		{
			arr++;
		}
		end = arr - 1;        //如果为空白符arr-1说明退至此单词末尾字母处,如果为‘\0' arr-1说明退至字符串结束位置处的前一位
		my_reverse(curr, end);
		if (*arr == ' ')        //指针指向的内容为空白符时,指针移动到下一单词的首字母处,去除了指向结束符时指针仍旧移动而越界的弊端
		{
			arr++;
		}
	}
}
int main()
{
	char arr[] = "student a am i";
	int sz = 0;
	sz= my_strlen(arr);
	//printf("%d\n", sz);
	reverse_str(arr,sz);
	printf("%s\n", arr);
	system("pause");
	return 0;
}

对第3题进行升级:

//int arr[]={ 1, 2, 3, 4, 4, 3, 1, 2, 5 ,9};
//一组数据中只有一个数字出现了一次。
//其他所有数字都是成对出现的。
//请找出这个数字。(使用位运算)
//不能申请新的数组,不能使用for嵌套


#include<stdio.h>
#include <stdlib.h>
void function(int *arr, int sz, int* x, int *y)
{
	int i = 0;
	int sum = 0;
	int pos = 0;
	//获取整个序列异或的结果
	for (i = 0; i < sz; i++)
	{
		sum = sum^arr[i];//
	}
	//找出从右往左起第pos位为1的位
	for (i = 0; i < 32; i++)
	{
		if ((sum >> i) & 1 == 1)
		{
			pos = i;
			break;
		}
	}
	//按上面的得到POS分割数组
	for (i = 0; i < sz; i++)
	{
		if (((arr[i] >> pos) & 1) == 1)
			*x = *x^arr[i];
		else
		{
			*y =*y^arr[i];
		}
	}
}
int main()
{
	int arr[] = { 1, 2, 3, 4, 4, 3, 1, 2, 5, 9 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int x = 0;
	int y = 0;
	function(arr, sz, &x, &y);
	printf("%d %d\n", x, y);
	system("pause");
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值