我想确定在用户输入的链接列表中哪些值和多少值是重复的。这是我为它写的代码:
int count;
int compare, compare2;
for (p = first; p != NULL; p = p->next){
compare = p->num;
for (j = first; j != NULL; j = j->next){
if (compare == j->num){
compare2 = j->num;
count++;
}
}
if (count > 1){
cout << "There are at least 2 identical values of: " << compare2 << " that repeat for: " << count << "times" << endl;
}
}
基本上它的想法是我在第一个循环中取第一个元素并将它与第二个循环中的所有元素进行比较,并计算它们是否相似,并在之后打印结果 - 然后我采取下一个元素等等。
然而输出是所有元素,它也没有正确计数。我只是迷失了如何调整它。
我尝试在两个循环中使用相同的p变量,因为它是我想要循环的相同列表,但是一旦我完成输入,.exe就会失败。
我看到了一些有关删除重复值的功能的示例,但是比较部分通过while循环运行,我只是想知道 - 我在这个上做错了什么?!
答案 0 :(得分:1)
您的 O(N * N)方法:
// Pick an element
for (p = first; p != NULL && p->next !=NULL ; p = p->next)
{ // Compare it with remaining elements
for (j = p->next ; j != NULL; j = j->next)
{
if ( p->num == j->num)
{
count++;
}
if( cout > 1 )
{
std::cout << p->num << " occurs "<< count << times << '\n' ;
}
}
最好使用HashMap来解决这个问题 O(N)时间 N 额外空间
std::unordered_map<int, int> m ;
for( p = first; p != NULL ; p = p->next )
{
m[ p->num ]++;
}
for (const auto &pair : m )
{
if( pair.second > 1 )
std::cout << pair.first << ": " << pair.second << '\n';
}
答案 1 :(得分:0)
问题是您不能排除与(compare
)比较的元素。因此,对于每个元素,它至少找到一个副本 - 本身!
尝试比较内循环中的元素,然后是当前(p
)。
答案 2 :(得分:0)
由于p
和j
遍历整个列表,因此您的逻辑存在缺陷。当p == j
时,值必须匹配。
更改块
if (compare == j->num){
compare2 = j->num;
count++;
}
到
if (p != j && compare == j->num){
compare2 = j->num;
count++;
}
此外,您不需要该行
compare2 = j->num;
因为compare2
将等于compare
。
您可以通过稍微更改内部for循环来减少测试次数。然后,您也不会需要p != j
位。
for (j = p->next; j != NULL; j = j->next){
if (compare == j->num){
count++;
}
}