一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字;喝汽水问题;实现strcpy,strcat

博客探讨了在数组中找到仅出现一次的两个数字的问题,提出了使用异或操作的解决方案。通过两重循环遍历数组,利用异或操作的特性(相同取0,不同取1)来定位这两个数字。
摘要由CSDN通过智能技术生成

1.一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
找出这两个数字,编程实现。
(1)原始作法:我们通过两重循环,逐次的对数组进行遍历.
#include <stdio.h>
#include <windows.h>

//找单独出现的数,一般方法
int search(int a[], int len)
{
	int i, j, k;
	for (i = 0; i < len; i++) {
		k = 0;
		for (j = 0; j < len; j++) {
			if (a[j] == a[i]) {
				k++;
			}
		}

		if(k == 1){
			printf("%d ", a[i]);
		}
		
	}
	printf("\n");
}

int main()
{
	int a[] = { 1,3,5,6,1,3,5,7 };
	int len = sizeof(a) / sizeof(a[0]);
	search(a, len);

	system("pause");
	return 0;
}
(2)用异或运算来解题,首先看一下异或的特点:

1.0^0=0,0^1=1,1^0=1,1^1=0,即相同取0,不同取1,那么相同的两个整数异或结果为0,任何整数与0异或都等于其本身

2.异或满足交换律,即a^b^c=a^c^b

所以,将数组中的数从头到尾依次异或,出现偶数次的数异或都为0,最终结果是两个只出现一次的数字异或的结果,由于这两个数字不同,异或的结果一定不为0,即其二进制表示形式中一定存在某一位为1,找到第一个为1的位,假设是第N位,那么在对应的这一位上,这两个数一个为0,一个为1,根据第N位是否为1,将原数组分成两个子数组,这两个子数组分中都只包含一个只出现了一次的数,其他的数都出现了两次,两个子数组中的元素分别异或,就得到了两个只出现一次的数。
#include <stdio.h>
#include <windows.h>

void search(int arr[], int len)
{
	int ret = 0;
	int inter = 0;
	int result1 = 0;
	int result2 = 0;
	for (int i = 0; i < len; i++)
	{
		ret ^= arr[i];
	}
	/*找ret最右边的1*/
	inter = ret - (ret&(ret - 1));
	for (int i = 0; i < len; i++)
	{
		int a = (arr[i] >> (inter - 1)) % 2;   //取出arr[i]的第inter位
		if (a == 0)
		{
			result1 ^= arr[i];
		}
		else
		{
			retsult2 ^= arr[i];
		}
	}
	printf("出现奇数次的两个数为: %d,%d\n", result1, result2);
}

int main()
{
	int arr[] = { 1, 3, 5, 6, 1, 3, 5, 7 };
	int len = sizeof(arr) / sizeof(arr[0]);
	search(arr, len);
	
	system("pause");
	return 0;
}
2.喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水。编程实现。
#include <stdio.h>
#include <Windows.h>
int drinkNum(int n)
{
	int count = n;
	while (n > 1)
	{
		count = count + n / 2;
		n = n / 2 + n % 2;
	}
	return count;
}

int main()
{
	int n = 20;
	int ret = drinkNum(n);
	printf("%d\n", ret);

	system("pause");
	return 0;
}

3.   模拟实现strcpy  
char *my_strcpy(char *dest, const char *src)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (*dest = *src)
	{
		dest++, src++;
	}
	return ret;
}

4.  模拟实现strcat 
char *my_strcat(char *dest, const char *src)
{
	char *ret = dest;
	assert(dest);
	assert(src);
	while (*dest)
	{
		dest++;
	}
	while (*dest = *src)
	{
		dest++, src++;
	}
	return ret;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值