算法
2012-10-20 21:27 露珠的微笑 阅读(242) 评论(0) 收藏 举报1、计算100!
const int NUM = 100;//设置要计算阶乘的数 int main() { int n = 0, i = 0, a[512] = {0}; int carry = 0;//进位数 double m = 0.0; for (n = NUM; n>0; n--)//算出结果含有的位数 m += (log(n)/log(10)); a[0] = 1;//我这里设置下标为0的存个数上的数值,初始值为1; for (n = 1; n<=NUM; n++) { carry = 0; for (i=0; i<m+1; i++) { a[i] = carry + a[i] * n; carry = a[i]/10; a[i] = a[i]%10; } }
2、 缺失的数字
根据:一个数和自己异或的结果为0
任何数与0异或都会不变的
很多成对出现数字保存在磁盘文件中,注意成对的数字不一定是相邻的,如2, 3, 4, 3, 4, 2……,由于意外有一个数字消失了,如何尽快的找到是哪个数字消失了?
由于有一个数字消失了,那必定有一个数只出现一次而且其它数字都出现了偶数次。用搜索来做就没必要了,利用异或运算的两个特性——1.自己与自己异或结果为0,2.异或满足交换律。因此我们将这些数字全异或一遍,结果就一定是那个仅出现一个的那个数。
View Code
static void Main(string[] args) { int[] a = {1, 347, 6, 9, 13, 65, 889, 712, 889, 347, 1, 9, 65, 13, 712}; int lostNum = 0; for (int i = 0; i < a.Length; i++) { lostNum ^= a[i]; } Console.WriteLine(lostNum); Console.Read(); }
3、数组中只出现1次的两个数字
设题目中这两个只出现1次的数字分别为A和B,如果能将A,B分开到二个数组中,那显然符合“异或”解法的关键点了。因此这个题目的关键点就是将A,B分开到二个数组中。由于A,B肯定是不相等的,因此在二进制上必定有一位是不同的。根据这一位是0还是1可以将A,B分开到A组和B组。而这个数组中其它数字要么就属于A组,要么就属于B组。再对A组和B组分别执行“异或”解法就可以得到A,B了。而要判断A,B在哪一位上不相同,只要根据A异或B的结果就可以知道了,这个结果在二进制上为1的位都说明A,B在这一位上是不相同的。
比如int a[] = {1, 1, 3, 5, 2, 2}
整个数组异或的结果为3^5即 0x0011 ^ 0x0101 = 0x0110
对0x0110,第1位(由低向高,从0开始)就是1。因此整个数组根据第1位是0还是1分成两组。
a[0] =1 0x0001 第一组
a[1] =1 0x0001 第一组
a[2] =3 0x0011 第二组
a[3] =5 0x0101 第一组
a[4] =2 0x0010 第二组
a[5] =2 0x0010 第二组
第一组有{1, 1, 5},第二组有{3, 2, 3},明显对这二组分别执行“异或”解法就可以得到5和3了。
View Code
static void Main(string[] args) { int[] a = { 1, 2, 3, 4, 1, 2, 3, 4, 0, 5 }; int p1=0, p2=0; FindTwoNotRepeatNumberInArray(a,ref p1,ref p2); Console.WriteLine("{0},{1}",p1,p2); Console.Read(); } public static void FindTwoNotRepeatNumberInArray(int[] a, ref int pn1, ref int pn2) { int temp = 0, j = 0; for (int i = 0; i < a.Length; i++) temp ^= a[i]; for (j = 0; j < sizeof(int) * 8; j++) if (((temp >> j) & 1) == 1) break; pn1 = 0; pn2 = 0; for (int i = 0; i < a.Length; i++) { if (((a[i] >> j) & 1) == 0) pn1 ^= a[i]; else pn2 ^= a[i]; } }

浙公网安备 33010602011771号