find number with no pair in array

匿名 (未验证) 提交于 2019-12-03 08:57:35

问题:

I am having trouble with a small bit of code, which in a random size array, with random number pairs, except one which has no pair.

I need to find that number which has no pair.

arLength is the length of the array. but i am having trouble actually matching the pairs, and finding the one which has no pair..

 for (int i = 0; i <= arLength; i++)         { // go through the array one by one..             var number = nArray[i];              // now search through the array for a match.             for (int e = 0; e <= arLength; e++)             {                 if (e != i)                 {                  }             }         } 

I have also tried this :

var findValue = nArray.Distinct(); 

I have searched around, but so far, i haven't been able to find a method for this.

This code is what generates the array, but this question isn't about this part of the code, only for clarity.

Random num = new Random();             int check = CheckIfOdd(num.Next(1, 1000000));             int counter = 1;              while (check <= 0)             {                 if (check % 2 == 0)                 {                     check = CheckIfOdd(num.Next(1, 1000000)); ;                 }                 counter++;             }             int[] nArray = new int[check];             int arLength = 0;             //generate arrays with pairs of numbers, and one number which does not pair.             for (int i = 0; i < check; i++)             {                 arLength = nArray.Length;                  if (arLength == i + 1)                  {                     nArray[i] = i + 1;                 }                 else                 {                     nArray[i] = i;                     nArray[i + 1] = i;                 }                 i++;             } 

回答1:

Distict will give you back the array with distinct values. it will not find the value you need.

You can GroupBy and choose the values with Count modulo 2 equals 1.

var noPairs = nArray.GroupBy(i => i)                     .Where(g => g.Count() % 2 == 1)                     .Select(g=> g.Key); 


回答2:

You can do it using the bitwise operator ^, and the complexity is O(n).

Theory

operator ^ aka xor has the following table:

So suppose you have only one number without pair, all the pairs will get simplified because they are the same.

var element = nArray[0];  for(int i = 1; i < arLength; i++)  {     element = element ^ nArray[i]; } 

at the end, the variable element will be that number without pair.



回答3:

You can use a dictionary to store the number of occurrences of each value in the array. To find the value without pairs, look for a (single) number of occurrences smaller than 2.

using System.Linq;  int[] data = new[] {1, 2, 3, 4, 5, 3, 2, 4, 1};  // key is the number, value is its count var numberCounts = new Dictionary<int, int>();  foreach (var number in data) {     if (numberCounts.ContainsKey(number)) {         numberCounts[number]++;     }     else {         numberCounts.Add(number, 1);     } }  var noPair = numberCounts.Single(kvp => kvp.Value < 2); Console.WriteLine(noPair.Key); 

Time complexity is O(n) because you traverse the array only a single time and then traverse the dictionary a single time. The same dictionary can also be used to find triplets etc.

.NET Fiddle



回答4:

An easy and fast way to do this is with a Frequency Table. Keep a dictionary with as key your number and as value the number of times you found it. This way you only have to run through your array once.

Your example should work too with some changes. It will be a lot slower if you have a big array.

    for (int i = 0; i <= arLength; i++)     {         bool hasMatch = false;         for (int e = 0; e <= arLength; e++)         {             if (nArray[e] == nArray[i])//Compare the element, not the index.             {                hasMatch = true;             }         }         //if hasMatch == false, you found your item.     } 


回答5:

All you have to do is to Xor all the numbers:

 int result = nArray.Aggregate((s, a) => s ^ a); 

all items which has pair will cancel out: a ^ a == 0 and you'll have the distinc item: 0 ^ 0 ^ ...^ 0 ^ distinct ^ 0 ^ ... ^0 == distinct



回答6:

Because you mentioned you like short and simple in a comment, how about getting rid of most of your other code as well?

var total = new Random().Next(500000) * 2 + 1; var myArray = new int[total]; for (var i = 1; i < total; i+=2) {     myArray[i] = i;     myArray[i -1] = i; } myArray[total - 1] = total; 

Then indeed use Linq to get what you are looking for. Here is a slight variation, returning the key of the item in your array:

var key = myArray.GroupBy(t => t).FirstOrDefault(g=>g.Count()==1)?.Key; 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!