c - 在输入中列出一个列表,删除所有重复项并计算它们的数量
问题描述
我试图实现这个功能,但有时我在运行时遇到问题。我需要输入一个像 1-2-3-2-4-6-1-2 这样的列表,并且该列表应该修改为 1-2-3-4-6 所以每个节点一次,我应该保存如何很多次是一个节点重复所以例如 1 重复 2 次 2 重复 3 次等。但有时它不起作用我不明白为什么。如果你按照我刚刚写的内容运行它,你会看到问题:多少节点:5 比写 1、1、2、4、2 和输出应该是 1、2 -> 2、2 -> 4(这意味着1重复两次,2重复两次,4重复1次)。如果我输入 1、2、3、2、1,我会得到“正确的输出”加上一个垃圾值。数字越高,它不起作用的可能性越大:(
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int val;
int rip;
struct Node *next;
} node;
node *modify(node *head);
void print(node *head2);
int main(){
int m, i;
printf("How many nodes: \n");
scanf("%d", &m);
node *head = NULL;
head = (node *)malloc(sizeof(node));
node *temp = head;
node *head2 = NULL;
for(i=0; i < m; i++){
temp->next = (node *)malloc(sizeof(node));
printf("Write the value in position %d: \n", i);
scanf("%d", &temp->val);
temp = temp->next;
temp->next = NULL;
}
head2 = modify(head);
print(head2);
return 0;
}
node *modify(node *head){
int counter, pass, m;
node *curr = head;
node *track = head;
while (track->next != NULL){
counter = 0;
pass = 0;
m = track->val;
while((curr)->next != NULL){
if(m == (curr)->val){
pass++;
counter++;
if(pass > 1){
node *removed = curr;
curr = (curr)->next;
free(removed);
}
if(pass == 1)
curr = curr->next;
}
else{
curr = (curr)->next;
}
}
track->rip = counter;
track = track->next;
curr = track;
}
return head;
}
void print(node *head2){
while(head2->next != NULL){
printf("%d, %d -> ", head2->val, head2->rip);
head2 = head2->next;
}
printf("\n");
}
解决方案
错误在这里:
if(pass > 1){
node *removed = curr;
curr = (curr)->next;
free(removed);
}
此代码释放了应该删除的节点,但没有将前一个节点链接到下一个节点,因此列表变得不正确。由于您不重新使用已释放的内存,它会保留其先前的值,但您确实会通过使用它来调用未定义的行为。
您必须跟踪以前的记录才能修复链接。一个可能的代码可能是:
while (track->next != NULL){
counter = 0;
pass = 0;
node *old = NULL;
m = track->val;
curr = track;
while((curr)->next != NULL){
node *next = curr->next;
if(m == (curr)->val){
pass++;
counter++;
if(pass > 1){
old->next = next; // old cannot be NULL because pass>1
free(curr);
curr = NULL;
}
}
if (curr != NULL) old = curr;
curr = next;
}
track->rip = counter;
track = track->next;
}
推荐阅读
- javascript - 如何使用 mongodb MongoClient 发出 GET 请求?
- python - 没有 fit() 的 Tensorboard 使用 keras 和 tf
- apache-spark - 在火花中加入 2 个数据帧后选择特定列
- c++ - C++ - std::unordered_map 中的最坏情况和平均情况插入时间复杂度
? - c# - 为什么我在 Linux/mono 上使用 PCLCypto 得到 DLLnotFoundException
- javascript - docker上的Nginx在刷新时出现404错误?
- f# - 在 F# 序列中需要帮助
- amazon-web-services - Cognito 验证 SAML - 什么是用户名约束?
- java - JUnit tests getter called before setter
- java - 尝试将值添加到单独类中的 ArrayList