从C中的数组“删除”

时间:2019-04-05 16:47:02

标签: c string struct

因此,我在存储车牌号的结构中有一个字符串数组,并且我想将出现次数超过1x(至少2次)的那些车牌号(一个车牌号可能会出现多次),但只有一次!

    typedef struct plates {
        char plate[10];
        char gate[25];
    } PL; //does not matter in this case

    PL r[50];
    int length = 50;
    char nullStr[5] = { '\0' };
    for (int i = 0; i < length; i++) {
        for (int j = i + 1; j < length; j++) {
            if (strcmp(r[i].plate, r[j].plate) == 0) {
                strcpy(r[j].plate, nullStr);
                fprintf(f_out, "%s\n", r[i].plate);
            }
        }
    }

输入:ASD123, QWE123, ASD123, KKR332, ASD123, QWE123,

输出应为:ASD123, QWE123

但我得到:ASD123, ASD123, QWE123

2 个答案:

答案 0 :(得分:3)

您的外部循环会考虑数组中的每个 元素,包括已经找到并打印为重复元素的元素。当只有两个副本时,这是无害的,但是如果要查找其他副本,则将打印其他副本。

您的内部循环会打印出找到的每张副本,即使它已经打印了车牌号。此外,您的外部循环不对在较早的迭代中复制到数组中的空字符串提供任何特殊处理,从而使程序易于与其他字符串进行匹配并打印(作为空白行)。

总体而言,您可以采用多种方法来解决此问题。一种方法是跟踪已经印制过的板号中的哪个板号(例如带有辅助数组),并在处理了一个板条后中止内部循环。另一种方法是在进行操作时修改数组,例如,将dupes设置为空字符串,然后在以后再次遇到空字符串时忽略它们。这就要求您不要过早退出内循环,而要在此跟踪当前的印版号是否已打印,从而避免多次打印。第三种是首先对阵列进行排序,使您可以将所有车牌号副本作为一个组进行处理,因为它们都位于阵列的相邻位置。

答案 1 :(得分:1)

每次找到副本时,印制板号,因此ASD123被打印两次,因为有3次。

此外,为此目的修改数组是不利的副作用。

您可以计算阵列中存在的车牌号的副本数,而只打印正好一份的车牌号。换句话说,仅打印任何车牌号的第一份副本:

typedef struct plates {
    char plate[10];
    char gate[25];
} PL; //does not matter in this case

PL r[50];
int length = 50;
// read the plate numbers, update length
for (int i = 1; i < length; i++) {
    int copies = 0;
    for (int j = 0; j < i; j++) {
        if (strcmp(r[i].plate, r[j].plate) == 0)
            copies++;
    }
    if (copies == 1)
        fprintf(f_out, "%s\n", r[i].plate);
}