有这样一个简单的问题:给定n-m+2(或n-m)个正整数组成的乱序序列,其元素是m到n(n>m>=1)中的互不相同的正整数,有且只有一个是重复(或缺失)的。如何找到那个数?(这里假定缺失的数不是n或m)
由Ivony提出的异或算法想到的。
1、由于[m,n]这段闭区间的异或算法暂时没有想到,所以就用[1,m-1]^[1,n]来间接得出[m,n]这段闭区间的异或。
2、求出待求数组的异或,将此结果再与上面[m,n]的异或结果再次异或,即可得到那唯一的一个重复数(或缺失的那个数)
1 using System.Linq; 2 using System; 3 namespace ConsoleApplication3 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int[] intergers = { 11, 8,9, 6, 12, 7, 5, 10, 14,13, 8 }; //[5,14],多一个8 10 Console.WriteLine(GetRepeatOrLack(intergers)); 11 Console.ReadKey(); 12 } 13 //给定n-m+2(或n-m)个正整数组成的乱序序列,其元素是m到n中的不同的整数,并有且只有一个是重复(或缺失)的。该算法返回那个数 14 private static int GetRepeatOrLack(int[] arrInts) 15 { 16 int temp = 0; 17 int upper = arrInts.Length; 18 //temp为数组arrInts中的所有数的异或结果 19 for (int i = 0; i < upper; i++) 20 { 21 temp = temp ^ arrInts[i]; 22 } 23 return temp ^ GetXor(arrInts.Min(), arrInts.Max()+1); 24 } 25 /// <summary> 26 /// 返回从start到end的连续若干个整数的异或结果 27 /// </summary> 28 /// <param name="start">开始位置(包含)</param> 29 /// <param name="end">结束位置(不包含)</param> 30 /// <returns>[start,end-1]闭区间异或结果</returns> 31 private static int GetXor(int start, int end) 32 { 33 if (start>=end) 34 { 35 throw new ArgumentException("end必须大于start"); 36 } 37 if (start + 1 == end) 38 { 39 return 0; 40 } 41 return GetXorFrom1ToN(start) ^ GetXorFrom1ToN(end); 42 } 43 /// <summary> 44 /// 返回从1到end的连续若干个整数的异或结果 45 /// </summary> 46 /// <param name="end">结束位置(不包含)</param> 47 /// <returns>[1,end-1]闭区间的异或结果</returns> 48 private static int GetXorFrom1ToN(int end) 49 { 50 if (end<=1) 51 { 52 throw new ArgumentException("参数end须大于等于2"); 53 } 54 if (2== end) 55 { 56 return 0; 57 } 58 int mod = (end - 1) % 4; 59 switch (mod) 60 { 61 case 0: 62 return end - 1; 63 case 1: 64 return 1; 65 case 2: 66 return end; 67 case 3: 68 return 0; 69 default: 70 return 0; 71 } 72 } 73 74 # region [1,n]闭区间的连续正整数的异或结果是有规律 75 //我们发现了[1,n]闭区间的连续正整数的异或结果是有规律的,即: 76 // 余数 [1,n]的异或结果Xor 77 // 0 n 78 // 1 1 79 //n mod 4 = 2 n+1 80 // 3 0 81 //所以下面的方法可以改造成上面的样子 82 //private static int GetXor(int start, int end) 83 //{ 84 // int result = 0; 85 // if (start + 1 == end) 86 // { 87 // return 0; 88 // } 89 // for (int i = start; i < end; i++) 90 // { 91 // result = result ^ i; 92 // } 93 // return result; 94 //} 95 #endregion 96 97 } 98 }
时间: 2024-12-17 19:38:39