简体   繁体   English

查找数组中没有对的数字

[英]find number with no pair in array

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. arLength是数组的长度。 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++;
            }

You can do it using the bitwise operator ^ , and the complexity is O(n) . 您可以使用bitwise^来完成它,复杂度为O(n)

Theory 理论

operator ^ aka xor has the following table: operator ^ aka xor有下表:

在此输入图像描述

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. 最后,变量element将是没有对的数字。

Distict will give you back the array with distinct values. Distict将为您提供具有不同值的数组。 it will not find the value you need. 它找不到你需要的价值。

You can GroupBy and choose the values with Count modulo 2 equals 1. 您可以使用GroupBy并选择Count modulo 2等于1的值。

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

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

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. 要查找不带对的值,请查找小于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. 时间复杂度为O(n),因为您只遍历数组一次,然后一次遍历字典。 The same dictionary can also be used to find triplets etc. 同一个字典也可用于查找三元组等。

.NET Fiddle .NET小提琴

All you have to do is to Xor all the numbers: 你所要做的就是Xor所有数字:

 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 所有具有对的项目都将取消: a ^ a == 0并且你将拥有distinc项目: 0 ^ 0 ^ ...^ 0 ^ distinct ^ 0 ^ ... ^0 == distinct

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. 然后确实使用Linq来获得你想要的东西。 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM