0

我需要将两个排序的名称文件合并为一个名称文件,消除任何重复的名称。

例如:

清单 1:

阿什利

詹姆士

凯文

佐伊

清单 2:

伊芙琳

詹姆士

卡尔文

韦恩

清单 3:

阿什利

伊芙琳

詹姆士

卡尔文

凯文

韦恩

佐伊


这是我的功能到目前为止的样子:

void funcmerge(char list1[][10], char list2[][10], char list3[][10])
{

}

List1 是放入字符串数组的第一个名称列表

List2 是放入字符串数组的第二个名称列表

List3 是从 List1 和 List2 合并的名称列表,没有重复。

4

1 回答 1

0

我建议为此解决方案修改合并排序的合并部分。创建两个计数器,每个列表一个。这两个计数器将保存它们各自数组的当前位置。然后,

  • 比较每个列表中的两个当前元素,
  • 将字典顺序较小的元素添加到 list3,
  • 增加包含较小元素的列表的计数器。
  • 重复直到到达数组的末尾。
  • 将另一个数组的其余部分添加到 list3。

如果两个元素在任何时候都相等,则只增加一个计数器并且不要向 list3 添加任何内容(这将确保只添加一次重复项)。

void funcmerge(char *list1[], char *list2[], char *list3[])
{
    int i = 0, k = 0, cnt = 0;

    // while both lists still contain elements
    while(list1[i] && list2[k]){
        int cmp = strcmp(list1[i], list2[k]);

        // if the names are equal, don't add anything to the list
        if (cmp == 0){
            k++;

        } else if (cmp < 0){
            list3[cnt++] = list1[i++];

        } else {
            list3[cnt++] = list2[k++];
        }
    }


    // if list1 still has elements, finish adding it to the list
    if (list1[i]){
        while (list1[i]){
            if (strcmp(list3[cnt - 1], list1[i])){
                list3[cnt++] = list1[i++];

            } else{
                i++;
            }
        }
    }

    // if list2 still has elements, finish adding it to the list
    if (list2[k]){
        while(list2[k]){
            if (strcmp(list3[cnt - 1], list2[k])){
                list3[cnt++] = list2[k++];

            } else{
                k++;
            }
        }
    }
}

但是,您应该注意我更改了函数的签名,并且我实现了这个算法,假设数组以空字符结尾。IE,

 char *list1[] = {"Ashley", "James", "Kevin", "Zoe", '\0'};
 char *list2[] = {"Evelynn", "James", "Kalvin", "Wayne", '\0'};

如果列表不以空字符结尾,则需要将数组长度硬编码到代码中(我不建议这样做),或者传入另外两个参数和两个数组的长度。

最后,您还需要获取 list3 的大小。我可以想到两种方法来解决这个问题。一种方法是返回 list3 的大小。只需添加return cnt;到函数的末尾。或者二,预先将整个数组设置为 null(我会使用memset())。然后,您可以遍历数组,直到遇到空元素。

于 2013-11-06T07:05:11.220 回答