Program.16(找出数组中两个只出现过一次的数字,喝汽水问题,自己实现实现strcpy,strcat)

博客包含三个编程问题。一是找出数组中仅出现一次的两个数字,通过异或和位运算实现;二是计算一定金额下喝汽水的数量,考虑空瓶兑换,还提及老板借瓶情况;三是模拟实现strcpy和strcat函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.一个数组中只有两个数字是出现一次, 
其他所有数字都出现了两次。 
找出这两个只出现一次的数字,编程实现。 

思路:

1. 通过所有数字异或得到结果sum.

 2.(进行位运算)将sum进行移位并与1得到数值为1的位,即第pos位.

3.利用pos位进行分割数组,在对分割完成的数组进行自身异或即可分出.

    实质上:  数组进行异或后得到的是5^9=1100(因为其他重复数字异或结果肯定是0), 即得到pos=2; 证明从第二位开始数组中两个不同数对应二进制位出现不同. 所以可以将数组中所有数字进行右移pos位再与1即可得到所有数字对应二进制的第二位, 最后只要将每一个数进行右移pos&1之后判断,是1则用变量x异或这个数,不为1用变量y异或这个数,就会分离开并得到这两个数.(最后一步实质是进行分离数组,然后根据pos位是否为1,分离后相同的数肯定在一组,在进行异或相乘即可).

 

#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, 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;
}


2.喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水, 
给20元,可以多少汽水。 
编程实现。 

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int money = 0;
	int num = 0;
	int empty = 0;
	printf("请输入金额: ");
	scanf("%d", &money);
	num = money;
	empty = money;
	while (empty > 1)//你手里的空瓶子数大于1,表明你还可以继续喝
	{
		num = num + empty / 2;//两个空瓶子可以换一瓶汽水
		empty = empty / 2 + empty % 2;//空瓶子数=换之后的瓶子+剩下的空瓶子
	}
	printf("可以喝 %d 瓶", num);
    //printf("剩余空瓶子数:%d\n", empty);
	system("pause");
	return 0;
}

 

注意:不要忘记统计空瓶子数时前一次换瓶子时剩下的瓶子数

有一个问题是假如20元,可以喝多少瓶,代码执行结果是39瓶,但emmm如果老板愿意借一个空瓶给你,实际可以喝到40瓶.因为之前剩1个空瓶,加上借的刚好可以多换一瓶,喝完后顺便可以把借的空瓶子还给老板.


3.模拟实现strcpy 

//3.模拟实现strcpy
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <assert.h>
char *my_strcpy(char *dest, const char*src)
{
	char *ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[] = "aavasv";
	char arr2[10] = "0";
	char *tem = my_strcpy(arr2, arr1);
	printf("%s\n", tem);
	system("pause");
	return 0;
}


4.模拟实现strcat 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <assert.h>
char *my_strcat(char *dest, const char*src)
{
	char *ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	while (*dest)
	{
		dest++;
	}
	while ((*dest++ = *src++))
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[] = "hello";
	char arr2[] = "  hhhhh";
	char *tem = my_strcat(arr1, arr2);
	printf("%s\n", tem);
	system("pause");
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值