«Удаление» из массива в C - PullRequest
0 голосов
/ 05 апреля 2019

Таким образом, у меня есть строковый массив в структуре, в котором я хранил номера автомобильных номеров, и я хочу напечатать те номера автомобилей (номерные знаки могут встречаться несколько раз), которые встречаются в файле более 1 раза (по крайней мере, 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 ]

3 голосов
/ 05 апреля 2019

Ваш внешний цикл учитывает каждый элемент вашего массива, включая те, которые уже были найдены и напечатаны как дубликаты.Это безопасно, когда есть только две копии, но если найдутся какие-либо дополнительные копии, вы распечатаете дополнительные материалы.

Ваш внутренний цикл печатает каждый дубликат, который он найдет, даже если онуже напечатал номерной знак.Кроме того, ваш внешний цикл не обеспечивает какой-либо специальной обработки для пустых строк, скопированных в массив на более ранних итерациях, поэтому ваша программа склонна сопоставлять их с другими и печатать их (в виде пустых строк).

В целом, существуетЕсть несколько способов решения проблемы.Один из них заключается в том, чтобы отслеживать, какие номера пластин являются дубликатами уже напечатанных - например, с помощью вспомогательного массива, - и прерывать внутренний цикл после обработки одного дублирования.Другим способом было бы изменить массив по мере использования, скажем, установив для dupes пустые строки, а затем игнорируя пустые строки, когда вы позже встретите их снова.Это требует, чтобы вы не выходили из внутреннего цикла раньше, а следили за тем, был ли уже напечатан текущий номерной знак, чтобы избежать его многократной печати.Третье - сначала отсортировать массив, что позволит вам обрабатывать все копии номера пластины как одну группу, поскольку все они будут находиться в смежных позициях массива.

1 голос
/ 05 апреля 2019

Номер пластины печатается каждый раз, когда вы находите копию, следовательно, 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...