假设我有5个整数。
int a = 1;
int b = 2;
int c = 5;
int d = 1;
int f = 1;
我想检查这5个整数中是否有3个相同。
我尝试了一些方法,但代码很长(500+行),我认为这不是一个好方法。
首先将它们全部放在一个集合中,而不是有单独的变量:
var numbers = new[]{a,b,c,d,f};
然后将它们分组,找到每个组的数量,并查看是否符合您的标准。
var isLargeGroup = numbers.GroupBy(n => n, (key, group) => group.Count() )
.Any(count => count >= 3);
IGrouping
参数。这会让世界变得更加容易。可惜它不是这样的。不过这很容易修复。 - ServyGroupBy
的第二个参数所做的)。最后,如果其中任何一个计数大于或等于三,则为true,否则为false。 - Servy其他两种解决方案对于大数据集(例如10000个数字)可能会很昂贵,需要完整枚举并创建许多将被垃圾回收的对象。尝试使用以下方法,它可以在完整枚举之前停止执行:
private bool AreNumbersTheSame(int[] numbers, int duplicateCount)
{
var numberCounts = new Dictionary<int, int>();
for (int i = 0; i < numbers.Length; i++)
{
var current = numbers[i];
if (!numberCounts.ContainsKey(current))
{
numberCounts[current] = 1;
continue;
}
if (numberCounts[current] == duplicateCount - 1)
{
return true;
}
numberCounts[current]++;
}
return false;
}
像这样调用:
var result = AreNumbersTheSame(new[] { a, b, c, d, f }, 3);
值得一提的是,这里有另一个选项,如果数据序列很大,则比GroupBy
更有效,虽然不太优雅。我认为,在扩展方法中隐藏了可读性并不是那么重要。
public static bool HasDuplicateCount<T>(this IEnumerable<T> seq, int maxCount)
{
Dictionary<T, int> counts = new Dictionary<T, int>();
foreach (T t in seq)
{
int count;
if (counts.TryGetValue(t, out count))
++count;
else
count = 1;
if (count == maxCount)
return true;
counts[t] = count;
}
return false;
}
bool threeDups = new[] { a, b, c, d, f }.HasDuplicateCount(3);
如果你想查看超过一半的元素是否相同(例如5个元素中有3个相同),那么这也可以使用多数投票算法来解决:
public static bool HasMajorityElement(int[] a)
{
int candidate = 0;
int count = 0;
foreach (int i in a)
{
if (count == 0)
{
candidate = i;
count = 1;
}
else
{
count += candidate == i ? 1 : -1;
}
}
count = 0;
foreach (int i in a)
{
if (i == candidate) ++count;
}
return count > a.Length / 2;
}
或者针对您的特定情况:
public static bool ThreeOutOfFive(int a, int b, int c, int d, int e)
{
return ((a==b?1:0)+(a==c?1:0)+(a==d?1:0)+(a==e?1:0) > 1)
|| ((b==c?1:0)+(b==d?1:0)+(b==e?1:0) > 1)
|| ((c==d?1:0)+(c==e?1:0) > 1);
}
将所有数字添加到列表中。
创建一个字典,以数字为KEY,以其出现次数为VALUE。
在迭代列表时,需要检查数字是否不在字典中,然后使用数字作为KEY并将1作为其VALUE添加。
如果数字重复出现,则只需将字典的VALUE增加1。
一旦它等于3,就跳出循环。
int a = 1;
int b = 2;
int c = 5;
int d = 1;
int f = 1;
var listOfNumbers = new List<int> {a, b, c, d, f};
var dict = new Dictionary<int, int>();
foreach (var number in listOfNumbers)
{
if (dict.ContainsKey(number))
{
dict[number] = dict[number] + 1; //如果键重复 => 将值增加1
if (dict[number] == 3)
break; //找到数字
}
else
dict.Add(number, 1); //对于键的第一次出现 => 将值初始化为1
}