C语言中的找特殊数字问题
2016-04-19 14:49
393 查看
在C语言的学习过程中,你一定遇到过如何在一个数组中找到一个特殊的数字,这个数字只出现一次,而其他数字都是成对出现的,请你找出这个特殊的数字。如果你是第一次遇到这个问题,那么可能你不能一下子想到最好的方法,当然也有可能你思维特别敏捷,一下子就可以想到最好的解决方法——异或,把这一串数字从头到尾异或,最终得到的那个数字就是你要找的数字。
附上代码:
具体的方法如下:
1. 首先数组中所有元素依次异或,因为相同的元素异或得到0,所以最终的答案就等于那2个唯一的元素a^b的值。
2. 因为a,b不同,所以异或得到的答案肯定是不等于0的,那么我们就找到a^b的二进制表示中第一个为1的位,假如是第k位。而a,b两个数在第k位上是不同的,一个为0,一个为1
3. 接下来我们将第k位是1的分成一组,第k位是0的分成一组,如果2个元素相同,那么他们第k位肯定是一样的,所以肯定被分到同一组中。而a,b则被分到2组中去了。
然后我们就可以在每个分组中异或每一个元素,最终就可以得到那2个唯一的元素
附上测试的代码:
附上代码:
#include<stdio.h> #include<stdlib.h> int main() { int N = 0, Special_Num = 0, i = 0; int * Pnum = NULL; printf("请输入您要测试的数据的个数:\n"); scanf("%d", &N); Pnum = (int *)malloc(sizeof(int)* N); printf("请依次输入您要测试的数据:\n"); for (size_t i = 0; i < N; i++) { scanf("%d", Pnum + i); Special_Num ^= *(Pnum + i); //从头到尾异或 } printf("这个特殊的数字是:%d\n", Special_Num); return 0; }那么如果将问题改下,改成在一个数组,或者在一堆数字之中找到两个特殊的数字,只有这两个数字出现一次,其他的数字都是成对出现,让你找出这两个数字,可以说这道题目与上面的题目很类似,那么一种数学思想就可以运用了,那就是分解思想,将一个问题分成你所遇到过的问题,比如既然这个数组之中有两个数字不同,那么你是不是可以将这两个数字分开来寻找,进一步思考 ,既然可以分开来寻找,那么可不可以将这个数组分成两个子数组,使得每个子数组中都只有一个唯一的元素以及很多成对的元素,那么我们就可以求出每个子数组中唯一的元素,最终就可以得到原数组中2个出现次数唯一的元素。
具体的方法如下:
1. 首先数组中所有元素依次异或,因为相同的元素异或得到0,所以最终的答案就等于那2个唯一的元素a^b的值。
2. 因为a,b不同,所以异或得到的答案肯定是不等于0的,那么我们就找到a^b的二进制表示中第一个为1的位,假如是第k位。而a,b两个数在第k位上是不同的,一个为0,一个为1
3. 接下来我们将第k位是1的分成一组,第k位是0的分成一组,如果2个元素相同,那么他们第k位肯定是一样的,所以肯定被分到同一组中。而a,b则被分到2组中去了。
然后我们就可以在每个分组中异或每一个元素,最终就可以得到那2个唯一的元素
附上测试的代码:
#include<stdio.h> #include<stdlib.h> int main() { int N = 0, i = 0; int * Pnum = NULL; int num1 = 0; int num2 = 0; int k = 1, j = 0; int end_num = 0; //测试用的数字 int flag = 0; printf("请输入您要判别的数字的个数\n"); scanf("%d", &N); Pnum = (int *)malloc(sizeof(int)*N); printf("请依次输入内容:\n"); for (int i = 0; i < N; i++) { scanf("%d",Pnum + i); } for (int i = 0; i < N; i++) { end_num ^= *(Pnum + i); //从头到尾异或 } while (!(end_num & 1)) //从最低位开始找,找到一个为1的数字,并记录位数 { flag++; end_num >>= 1; } for (int i = 0; i < N; i++) { int tmp = Pnum[i] >> flag; //根据这个位数将数组分为两组,两个数字被分在不同的组 if (tmp & 1) { num1 ^= Pnum[i]; } else { num2 ^= Pnum[i]; } } printf("您要找的数字为:%d %d", num1, num2); return 0; }其实很多问题都可以完成从复杂到简单的转化,有时候知识我们没想到怎么转化而已。
相关文章推荐
- 控制符endl与换行符'\n'的区别
- 第4周 C语言及程序设计提高例程-4 函数的返回值
- 关于C/C++中的inline
- C++ 类的三种构造函数(默认构造,拷贝构造,赋值构造),在什么情况下会被调用
- 谈谈基类与子类的this指针(C++)
- [c++]非局部静态对象初始化顺序
- 语法错误 : 缺少“;”(在“类型”的前面)
- 详解C++中的const关键字及与C语言中const的区别
- 用C++使用Android Log API输出日志
- c语言中的break和continue
- C++隐藏规则
- C语言之字符串的表示方式
- protobuf c++ api 简介
- 用1元,2元,5元,10元,20元,50元组合成100元
- C++ WINDOWS API 如何使用NMAKE和CL编译
- C++学习笔记十六 - 文本处理string.H 类的用法,
- C++访问声明
- 关于C语言中参数的传值问题
- C++学习笔记十五 - C++的类
- AllJoyn+Android+C++开发案例-android和windows跨设备跨平台调用方法