比较C#中的两个数组并打印丢失的数字

时间:2016-10-31 17:07:02

标签: c# linq

我对C#很陌生,无法检查两个字符串之间的区别,数字用空格分隔,并返回第二个字符串中缺少的数字。

$file = 'filename_'.rand(5,15).'.gif';

exec("convert 'images/highres/bg/deer_and_snow_blue.gif' -coalesce -interline-spacing 2 -font fonts/FredokaOneRegular.ttf -fill black -pointsize 16 -annotate +220+520 \"This is some sample text here \" null: \( 'images/uploads/cganewlogored.jpeg' -resize 165.34736842105264x84 -coalesce \) -geometry +666.652631579+501 -layers Composite " . $file);

echo '<img src="'.$file.'" />';

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

   // 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);

我不确定我做错了什么。我查看了建议用于比较C#中的两个数组的所有可能的解决方案,并尝试了使用LINQ和两个for循环的不同方法,但我无法弄清楚它们。 谢谢你的帮助。

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

4 个答案:

答案 0 :(得分:3)

尝试使用字典,其中键是字符串(&#34; 503&#34;等),并且值是该元素的出现次数(因此,如果503重复3次键值对将是&lt; 503,3&gt;)。

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

  

在你的情况下,词典看起来像

一个__________乙__________结果

&lt; 503,2&gt; ___&lt; 503,2&gt; ____

&lt; 504,1&gt; ___&lt; 504,3&gt; ____ 504,2列表B中出现更多

...等

以下是如何在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)。

答案 1 :(得分:0)

抱歉,我之前的回答是假设有些东西&#34;错误&#34;使用代码,我没有更彻底地看待它。如前所述,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);

答案 2 :(得分:0)

这个怎么样?我们得到列表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));
            }
        }

答案 3 :(得分:0)

如果对某人有用,请提供一些反馈意见。这是我的最终解决方案。它解决了我的练习中的所有测试用例,除了一个。我们在每个阵列中有1 000 000个整数。如果我们有两个超过一百万个数字的字符串,每个字符串用空格分隔,那么这样做的有效方法是什么。

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);
}