将两个已排序的名称数组合并为一个新数组,从而消除重复(C语言)

时间:2013-11-06 05:38:47

标签: arrays list merge

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

例如:

列表1:

阿什利

詹姆斯

凯文

佐伊

列表2:

伊芙琳

詹姆斯

卡尔文

韦恩

列表3:

阿什利

伊芙琳

詹姆斯

卡尔文

凯文

韦恩

佐伊


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

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

}

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

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

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

1 个答案:

答案 0 :(得分: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++;
            }
        }
    }
}

但是,你应该注意我改变了你的函数的签名,我实现了这个算法,假设数组以空字符结尾。即,

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

如果列表不以空字符结尾,您将需要将数组长度硬编码到代码中(我不建议),或者使用两个数组的长度传递另外两个参数。 / p>

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