int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int count = 0;
for (int j = 0; j < array.Length; j++)
{
if (array[i] == array[j])
{
count = count + 1;
}
}
Console.WriteLine(array[i] + " repeats " + count + " times");
}
Console.ReadKey();
我不想使用LINQ! 我的问题是,如何只打印一次结果。例如:
10次重复2次
5次重复3次
2次重复2次
...
感谢。
答案 0 :(得分:2)
如果没有LINQ,你可以这样做:
var dictionary = new Dictionary<int, int>();
foreach (var element in array)
{
dictionary[element] = (dictionary.ContainsKey(element) ? dictionary[element] : 0) + 1;
}
foreach (var pair in dictionary)
{
Console.WriteLine(pair.Key + " repeats " + (pair.Value - 1) + " times");
}
将它与LINQ进行比较,你就会知道为什么它很糟糕:
foreach (var number in array.GroupBy(x => x))
{
Console.WriteLine(number.Key + " repeats " + (number.Count() - 1) + " times");
}
编辑:将count
更改为(count - 1)
,因为OP需要重复次数,而不计算在内。
答案 1 :(得分:1)
您可以使用词典实现所需。
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
var dict = new Dictionary<int, int>();
foreach (var num in array)
{
if (!dict.ContainsKey(num))
{
dict.Add(num, 0);
}
dict[num]++;
}
foreach (var kvp in dict)
{
Console.WriteLine("{0} repeats {1} times", kvp.Key, kvp.Value);
}
答案 2 :(得分:0)
使用字典:
var results = new Dictionary<int, int>();
...
if (array[i] == array[j])
{
if (!results.ContainsKey(i)) results.Add(i, 0);
results[i]++;
}
...
//after loop
foreach (var pk in results)
{
Console.WriteLine("{0} repeats {1} times", pk.Key, pk.Value);
}
但这不是最佳解决方案 - 可以在O(n)
时间内完成。
答案 3 :(得分:0)
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
Dictionary<int, int> duplicateCounters = new Dictionary<int, int>();
foreach (int i in array)
if (!duplicateCounters.ContainsKey(i))
duplicateCounters[i] = 1;
else
++duplicateCounters[i];
foreach (var item in duplicateCounters)
if (item.Value > 1)
Console.WriteLine("{0} repeats {1} times", item.Key, item.Value);
答案 4 :(得分:0)
想象一下自己动手吧。你会得到一张白纸和一支笔。你会看看每个号码,然后去看看我的表格上的这个数字吗?&#34; - 不这么写&#34; 10,1&#34;在表单上替换&#34; n,count&#34; by&#34; n,count + 1&#34;
现在你有一张说
的表格10,2
0,4
7,42
等(注意我没有用样本数据验证这些计数)
只需将该逻辑转换为代码即可。提示你需要
Dictionary <int, int>
作为你的纸张
答案 5 :(得分:0)
您可以使用辅助数据结构来跟踪您找到的号码以及找到该号码的次数。
e.g。
Dictionary<int, int> dict = new Dictionary<int, int>();
...
if (array[i] == array[j])
{
if (dict.ContainsKey(array[i]))
{
dict[array[i]] += 1;
}
else
{
dict.Add(array[i], 1);
}
}
...
foreach (int key in dict.Keys)
{
Console.WriteLine(key + " repeats " + dict[key] + " times");
}
我希望它有所帮助...
答案 6 :(得分:0)
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int count = 0;
for (int j = 0; j < array.Length; j++)
{
if (array[i] == array[j])
{
count = count + 1;
}
}
Console.WriteLine(array[i] + " repeats " + count + " times");
}
Console.ReadKey();
看到多个控制台写入是有原因的。您正在将第一个elem(10)与数组中的所有元素进行比较。所以还有另外10个,您的代码可以检测到。
但是在第三遍时,您正在将第三个元素(10)与第一个元素(10)进行比较。您不是已经检查过了吗?如果a == b
,b == a
:)
您的代码中存在第二个错误。 i = 0
和j = 0
。你看到了吗?您正在将第一个元素与其自身进行比较!你想要什么?当然array[0] == array[0]
,这是相同的元素:)
每当i == j
时,您就在将每个元素与其自身进行比较。
您可能会将代码执行视为正方形i*j
,其中i和j是array.Length。因为i == j
,所以称为二次方。 i*j == i*i == i^2. O(i^2)
。
你能做什么?看这段代码:
int[] array = { 10, 5, 10, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12 };
for (int i = 0; i < array.Length; i++)
{
int count = 1;
for (int j = i + 1; j < array.Length; j++)
{
if (array[i] == array[j])
{
count = count + 1;
}
}
// if (count != 1)
Console.WriteLine(array[i] + " repeats " + count + " times");
}
Console.ReadKey();
除了int j = i + 1;
外,它几乎几乎一样,因为您永远不会将项目与其自身进行比较,并且将迭代次数减少了一半。 O(n ^ 2/2)。基本上在一个三角形上切一个正方形。听起来不错吧?但是/ 2优化将在array.Length增加1时就消失。而且我们的控制台报告仍然包含重复项。
如果有评论。该黑客“修复”了报告。您能发现错误吗?如果将数字11更改为10,将会报告什么?
因此,这表明在遍历数组时不可能编写报告,因为您没有记住以前的计数。一种选择是像其他答案中所建议的那样,使用哈希或二叉树来提交内存中的每个值。这需要额外的内存。第二种选择是销毁/删除/清空相同的物品,这并不便宜...
学习愉快:)