Удаление структур из массива - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь реализовать функцию, которая перебирает отсортированный массив структур и, если у «ключа» (первого значения поля) есть дубликат, он сохранит первую итерацию этой пары ключ-значение и удалит любые дубликаты, которые идут после. Вот мой код:

#include <stdlib.h>
#include <stdio.h>

struct Map * collect_values(int n, int *arr);
void sort_values(struct Map *ptr, int n);
void print(struct Map *print_struct, int n);
struct Map * remove_duplicates(struct Map *ptr, int n);

struct Map{
    int value, position;
};

int compare(const void *ptr1, const void *ptr2){
    const struct Map *aptr = ptr1;
    const struct Map *bptr = ptr2;

    if(aptr->value == bptr->value){
        return (aptr->position > bptr->position) - 
(aptr->position < bptr->position);
    }
    else{
        return (aptr->value > bptr->value) - (aptr->value < bptr->value);
    }
}

int compare2(const void *aptr, const void *bptr){
    int a = ((struct Map*)aptr)->position, b = ((struct 
Map*)bptr)->position;
    return (a > b) - (a < b);
}

int main(){
    int size, i;
    scanf("%d", &size);
    int *arr = (int*) malloc(size*sizeof(int));
    struct Map *p = collect_values(size,arr);
    printf("Struct before sorting:\n");
    print(p,size);
    qsort(p,size,sizeof(struct Map),compare);
    printf("Struct after sorting\n");
    print(p,size);
    struct Map *p2 = remove_duplicates(p,size);
    printf("\nStruct after removing in the main\n");

    for(i = 0; i < sizeof(*p2); i++){
         printf("%d : %d\n", p2[i].value, p2[i].position);
    }
    free(p);
    free(arr);
    free(p2);
    return 0;
 }

struct Map * collect_values(int n, int *arr){
    int i, position = 0;
    struct Map *array = calloc(n,sizeof(*array));
    for(i = 0; i < n; i++){
        scanf("%d",&arr[i]);
        array[i].value = arr[i];
        array[i].position = position;
        position++;
    }
    return array;

}

void print(struct Map * print_struct, int n){
    int i;
    for (i = 0; i < n; i++){
        printf("%d : %d\n", print_struct[i].value, print_struct[i].position);
    }
}

struct Map * remove_duplicates(struct Map *ptr, int n){
    int i, j = 0, newsize;
    struct Map *new_struct = calloc(n,sizeof(*new_struct));
    new_struct[0] = ptr[0];
    for(i = 1; i < n; i++){
        if(ptr[j].value != ptr[i].value){
            j++;
            new_struct[j].value = ptr[i].value;
            new_struct[j].position = ptr[i].position;
        }
    }
    newsize = j+1;
    //new_struct = realloc(new_struct, newsize);

    printf("\nSorting in the function:\n");
    for(i = 0; i < newsize; i++){
        printf("%d : %d\n", new_struct[i].value, new_struct[i].position);
    }
    return new_struct;
}

В функции remove_duplicates () я ожидаю, что это мой результат:

-3 : 3
1 : 9
3 : 2
4 : 1
5 : 4
7 : 6
25 : 0
88 : 7

Однако я получаю дополнительное значение ключа 5: 5, которое не удаляется как таковое:

-3 : 3
1 : 9
3 : 2
4 : 1
5 : 4
5 : 5
7 : 6
25 : 0
88 : 7

Я попытался обойти это вручную, и я думаю, что я делаю ошибку с j ++, потому что кажется, что условие ложно (т. Е. Есть дубликат), я повторяю, пока j остается, и я думаю, возможно, поэтому я удаляю дубликат 4, но не дубликат 5.

Куда я иду не так? Я также чувствую себя странно из-за жесткого кодирования значения с индексом 0, но очевидно, что первое значение не является тем, которое я хочу удалить (необходимо удалить только последующие значения, которые являются дубликатами), и, поскольку я начинаю с 1, оно не ' сравнивать.

Наконец, функция remove_duplicate () возвращает тип struct *. Когда я печатаю с основного, я получаю следующий вывод:

-3 : 3
1 : 9
3 : 2
4 : 1
5 : 4
5 : 5
7 : 6
25 : 0

Последнее значение по какой-то причине не указано. Я хотел бы, чтобы моя функция удаления была доступна из основного, так как я хочу передать указатель p2 другой функции, которая сортирует по значениям в паре ключ-значение. Что происходит с моим последним значением?

РЕДАКТИРОВАТЬ С ВХОДОМ И ОЖИДАЕМЫМ ВЫХОДОМ

Входные данные - это массив значений типа int, которые я преобразую в структуру value, position. Так, например, input является [25,4,3, -3,5,5,7,88,4,1], создаваемая структура:

 25 : 0
 4 : 1
 3 : 2
-3 : 3
 5 : 4
 5 : 5
 7 : 6
88 : 7
 4 : 8
 1 : 9

Мой код сортирует значения по полю значения структуры, после чего удаляются любые дублирующиеся пары ключ-значение. Таким образом, ожидаемый результат будет:

-3 : 3
 1 : 9
 3 : 2
 4 : 1
 5 : 4
 7 : 6
25 : 0
88 : 7

Где удаляются дублирующиеся пары (4,8) и (5,5).

1 Ответ

0 голосов
/ 13 сентября 2018

Это ваш ожидаемый результат

Struct before sorting:
25 : 0
4 : 1
3 : 2
-3 : 3
5 : 4
5 : 5
7 : 6
88 : 7
4 : 8
1 : 9
Struct after sorting
-3 : 3
1 : 9
3 : 2
4 : 1
4 : 8
5 : 4
5 : 5
7 : 6
25 : 0
88 : 7

Sorting in the function:
-3 : 3
1 : 9
3 : 2
4 : 1
5 : 4
7 : 6
25 : 0
88 : 7

Struct after removing in the main
-3 : 3
1 : 9
3 : 2
4 : 1
5 : 4
7 : 6
25 : 0
88 : 7

Просто измените условие if с if (ptr [j] .value! = Ptr [i] .value) на if (new_struct [j] .value! = Ptr [i] .value) в remove_duplicate ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...