繁体   English   中英

在C#中比较两个数组并打印缺少的数字

[英]Comparing two arrays in C# and printing the numbers that are missing

我是C#的新手,无法检查两个字符串之间的差异,这些数字之间用空格隔开,并返回第二个字符串中缺少的数字。

   // Initial String with numbers
    string stringA = "503 504 505 506 507 508 503 504 505 506"
    string stringB = "503 504 504 505 506 507 505 508 503 506 505 506 504"

    // I them split them into arrays
    string[] inputArrayA = stringA.Split();
    string[] inputArrayB = stringB.Split();

    // I change them to integers
    int[] numbersA = Array.ConvertAll(inputArrayA, int.Parse);
    int[] numbersB = Array.ConvertAll(inputArrayB, int.Parse);

    // Change the int[] array's to Lists
    var listN = new List<int>(numbersA);
    var listM = new List<int>(numbersB);

    // Compare the lists and put in an array the numbers that are missing from listN
    var missinNumbers = listM.Except(listN).ToList();

    // Print List contents
    missinNumbers.ForEach(Console.WriteLine);

但这现在不起作用。 我尝试使用HashSet实现单独的方法。 但是由于某种原因,missinNumbers始终为空。

public static IEnumerable<int> FindMissing(IEnumerable<int> mainList, IEnumerable<int> listToCompare)
{
    // Compare lists and return values that aren't in mainList but are in listToCompare
    HashSet<int> convertedToHash = new HashSet<int>(mainList);
    convertedToHash.ExceptWith(listToCompare);
    return convertedToHash;
}

我不确定自己在做什么错。 我研究了建议的所有可能的解决方案,以比较C#中的两个数组,并尝试了使用LINQ和两个for循环的不同方法,但是我都无法解决。 谢谢您的帮助。

编辑:我的目标是打印stringA与stringB相比缺少的数字。 因此,如果我们对这两个数组进行排序,我们可以看到缺少的数字是:504505506。

尝试使用一个词典,其中键是字符串(“ 503”等),值是该元素的出现次数(因此,如果503重复3次,则键值对将为<503,3>)。

您可以为2个列表创建2个字典,然后遍历其中一个并在第二个中查找元素,然后减去出现的次数以找出该键还剩下多少个元素。

在您的情况下,字典看起来像

A__________B__________结果

<503,2> ___ <503,2> ____

<504,1> ___ <504,3> ____ 504,列表B中另外2次出现

...等等

这是您可以在C#中完成的方法

string stringA = "503 504 505 506 507 508 503 504 505 506";
string stringB = "503 504 504 505 506 507 505 508 503 506 505 506 504";

// linq to make dictionary from A
var mapA = stringA.Split().GroupBy(a => a)
                          .Select(a => new {a.Key,Count = a.Count()})
                          .ToDictionary(a => a.Key, a => a.Count);

// linq to make dictionary from B
var mapB =  stringB.Split().GroupBy(b => b)
                           .Select(b => new { b.Key, Count = b.Count() })
                           .ToDictionary(b => b.Key, b => b.Count);

// Elements that are in B but not in A 
var BminusA = mapB.Select(b => { int aCount; 
                                 return new {b.Key, Value = b.Value - (mapA.TryGetValue(b.Key, out aCount) ? aCount: 0)};})
                  .Where(difference => difference.Value > 0);

上面的代码还会为您提供丢失数字的计数({504、505、506}分别为1)。

抱歉,我先前的回答是假设代码中存在“错误”,并且我没有更全面地研究它。 如前所述,仅当元素完全存在于另一个列表时, Except才会在执行检查时不考虑数量。 有一种LINQ方式可以执行您想要的操作,但是手动执行起来更容易阅读(更不用说更快了)。

for (int i = 0; i < listN.Count; i++)
{
    if (listM.Remove(listN[i]))
    {
        listN.RemoveAt(i--);
    }
}

for (int i = 0; i < listM.Count; i++)
{
    if (listN.Remove(listM[i]))
    {
        listM.RemoveAt(i--);
    }
}

此后,将用listN中不存在的所有特定元素填充listM ,反之亦然。

如果要将两个差异列表合并到一个集合中,则只需执行以下操作:

var differences = new List<int>(listM);
differences.AddRange(listN);

这个怎么样? 我们得到列表b中每个不同字符串的计数,如果与列表a中的计数之间的差为正,则将字符串的许多副本添加到丢失的列表中。

        string[] stringA = "503 504 505 506 507 508 503 504 505 506".Split();
        string[] stringB = "503 504 504 505 506 507 505 508 503 506 505 506 504".Split();

        List<int> missingNumbers = new List<int>();

        foreach (string num in stringB.Distinct())
        {
            int difference = stringB.Where(x => x == num).Count() - stringA.Where(x => x == num).Count();
            for (int i = difference; i > 0; i--)
            {
                missingNumbers.Add(int.Parse(num));
            }
        }

如果对此提供一些反馈,可能对某人有用。 这是我的最终解决方案。 它解决了我练习中的所有测试用例,只有一个除外。 每个数组中有1000000个整数。 如果我们有两个字符串,每一个字符串之间用空格隔开,那么这将是一种有效的方法。

static void Main(String[] args)
{
    // Build Array N from input numbers
    string[] inputLineN = Console.ReadLine().Split();

    // Build Array M from second input numbers
    string[] inputLineM = Console.ReadLine().Split();

    // Convert to int[] array
    int[] numbersN = Array.ConvertAll(inputLineN, int.Parse);
    int[] numbersM = Array.ConvertAll(inputLineM, int.Parse);

    // Convert them to Lists
    var listN = new List<int>(numbersN);
    var listM = new List<int>(numbersM);

    for (int index = 0; index < listN.Count; index++)
    {
        // Remove first occurance of item from listM if it exists in listN
        if (listM.Remove(listN[index]))
        {
            // Remove listN[index] and decrement the index to -1 so that the next iteration
            // starts from 0 again otherwise we will start at 1 and skip an item
            listN.RemoveAt(index--);
        }
    }

    // Sort missing items and join them back in a single string
    listM.Sort();
    int[] removeDuplicates = listM.Distinct().ToArray();
    string missingNumbers = string.Join(" ", removeDuplicates);

    Console.WriteLine(missingNumbers);
}

暂无
暂无

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

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