[英]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.