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