【问题标题】:How to remove the duplicate strings from an array of strings in c如何从c中的字符串数组中删除重复的字符串
【发布时间】:2020-07-13 21:40:07
【问题描述】:

我正在尝试制作程序,其中我有一个链接列表,其中包含不同的城市名称+一些其他不相关的东西。城市名称是,例如。 “西雅图、波士顿、纽约、西雅图、华盛顿、波士顿”。我想做的是制作一个只有城市名称的数组。因此,举个例子,它会是这样的:“西雅图、波士顿、纽约、华盛顿”。

我的想法是制作一个原始字符串数组,这将只是包含所有重复项的原始数据,然后遍历每个城市并将它们的所有其他外观设为“NULL”。由于某种原因,它无法正常工作,我不知道为什么。

另外,如果你们能用自己的、更简单的解决方案版本帮助我,我将不胜感激。

这是我的代码:

void city_list(City *head)
{
    City *temp = head;

    char** names_raw;
    char** names_new;
    int num_names = 100;
    int curr_pos = 0;

    names_raw = malloc(num_names * sizeof(char*));

    for(int i = 0; i < num_names; i++)
    {
        names_raw[i] = malloc(256 * sizeof(char));
    }

    while(temp != NULL)
    {
       
        strcpy(names_raw[curr_pos++], temp->name);

        temp = temp->next;
    }

    names_new = malloc(num_names * sizeof(char*));

    for(int i = 0; i < num_names; i++)
    {
        names_new[i] = malloc(256 * sizeof(char));
    }

    for(int i = 0; i < curr_pos; i++)
    {
        if(strcmp(names_raw[i], "NULL"))
        {
            for(int j = i+1; j < curr_pos; j++)
            {
                if(!strcmp(names_raw[j], names_new[i]))
                {
                    strcpy(names_raw[j], "NULL");
                }
            } 

            strcpy(names_new[i], names_raw[i]);
        }
    }

    for(int i = 0; i < curr_pos; i++)
    {
        printf("%s\n", names_new[i]);
    }

    free(names_raw);
    free(names_new);
}

当我调试代码时,我没有收到任何错误,但它会打印出所有城市,就像没有对数组做任何事情一样。

【问题讨论】:

  • 嗯,首先,你真的不需要复制这些字符串两次来做你想做的事......你呢?其次,我希望您确定名称短于 256 个字符,否则您的代码中存在多种缓冲区溢出的可能性。更安全的复制方式是strncpy()
  • @MarcoBonelli 我确实知道这些名称少于 256 个字符,但在给我的作业中,他们明确表示要使用我所做的最多 256 个字符的字符串。
  • 问题出在第二个strcmp,它将raw[j]new[i] 进行比较。那时代码中的new[i] 中没有任何内容。一旦你解决了这个问题,下一个问题就是将raw[i] 复制到new[i]strcpy。那应该是将raw[i]复制到new[k]

标签: arrays c string pointers


【解决方案1】:

您还没有向我们展示一个完整的示例(什么是“城市”?您的输入数组是如何构建的?等等)。但我怀疑你把事情弄得太复杂了:(

建议:

  1. 将您的数组传递到名为 int delete_dupes(char* arr[], int n)(或类似)的函数中

  2. 对数组进行排序:

    示例代码:https://www.geeksforgeeks.org/c-program-sort-array-names-strings/

  3. 通过将重复项移动到数组的前面来“删除”它们

    int delete_dupes(char* arr[], int n) {
      char *current_name = arr[0];
      int i=1, j=1;
      while (i < n) {
        if (strcmp(arr[i], current_name) != 0) {
          free(arr[j]);  /* Do *NOT* do this if you didn't malloc() this string!!!! */
          arr[j++] = arr[i];
          current_name = array[i];
        }
      }
      return j;
    }
    
  4. 函数返回新的#/strings。该数字将是

    此外,您可能希望清空未使用的数组元素和/或释放重复的字符串值。

  5. “理想”的解决方案是让您实现动态列表。

  6. 如果您想单独“malloc()”每个字符串,请考虑标准 C 库函数strdup()

不,我没有测试过:)

【讨论】:

  • 如果城市不在相同大小的缓冲区中,strcpy 不会做你想做的事。但是你甚至不需要 strcpy;您可以直接分配(并确保在必要时释放覆盖的元素)
  • 好点 - 示例已修改。但未编译或测试;)
猜你喜欢
  • 2018-06-09
  • 2012-05-09
  • 1970-01-01
  • 2011-03-23
  • 2011-08-08
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多