2014-12-12 4 views
0

Я заметил, что после создания его первой проверки Дубликат, а затем обе указывают на одного и того же млекопитающего, поэтому, когда я тогда называю great_circle, который работает на расстоянии между двумя, я получаю список 0, потому что это сравнивая одно и то же Млекопитающее.Удаление похожих предметов из связанного списка

void remove_duplicates() { 
int i,j; 
double distance; 
Mammal *next=head2.pointer; 
for(i=0;i<list_length2-1;i++) { 
    Mammal *check=next->pointer; 
    Duplicate *d=malloc(sizeof(Duplicate)); 
    d->mampointer=NULL; 
    d->number_of=0; 
    for(j=0;j<(list_length2-i)-1;j++) { 
     distance=great_circle(next->location, check->location); 
     if(distance<=0.02 && next->species==check->species) { 
      Mammal *a=next; 
      Mammal *b=check; 
      a->pointer=d->mampointer; 
      d->mampointer=a; 
      b->pointer=d->mampointer; 
      d->mampointer=b; 
      d->number_of++; 
      d->number_of++; 
     } 
     printf("%f\n",distance); 
     if (check->pointer!=NULL) { 
      check=check->pointer; 
     } 
    } 
    if(d->mampointer!=NULL) { 
     add_duplicate(create_duplicate(d)); 
    } 
    if (next->pointer!=NULL) { 
     next=next->pointer; 
    } 
} 
} 

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

EDIT: Проблема, которую я пытаюсь решить это:

Есть несколько млекопитающих с широты и долготы координат,

Некоторые из млекопитающих были зарегистрированы несколько раз, но немного отличается координаты,

Мне нужно найти эти дубликаты и заменить их одним млекопитающим со средним числом «неправильных» коорд.

+1

В: Каков ваш алгоритм для «удаления дубликата»? Не могли бы вы объяснить, что должен делать код? Q: Что такое «great_circle()»? В: Почему вы «add_duplicate()» внутри «remove_duplicates()»? В: В чем именно проблема, которую вы пытаетесь решить? – FoggyDay

+0

См. Править для получения дополнительной информации – Jim006Jam

+0

Это поможет, если вы действительно сможете очистить свой код. 'check-> pointer' не должна ваша номенклатура быть' check-> next', а вместо 'Mammal * next' должна быть' Mammal * mPointer'. Я бы также посоветовал для более форматирования здесь 'if (distance <= 0.02 && next-> species == check-> species)' должен быть 'if ((distance <= 0.02) && (next-> species == check-> виды)) 'его способ короткого замыкания статута. – KillaBytes

ответ

0

Посмотрите на этой ссылке: http://www.cprogramdevelop.com/2252274/ Это поможет вам пройти ваш связанный список без избыточности (и запутанных) указателей как head2 и т.д.

На первом взгляд кажется, комментарий Kozmik правилен о check->pointer должен быть check->next - но опять же, старайтесь избегать избыточных указателей, если только код не читается.

я найти изящный способ траверс связанный список, чтобы остановить, когда cur_node->next == NULL, а не позволяя «пустые» узлы и того, чтобы проверить, если cur_node->next->item == NULL (я предполагаю, что cur_node->pointer имеет в виду предмет, который вы сохраняете в этом узле).

Например:

typedef struct node_s { 
    void * item; // the item you are storing in this node 
    node_s * next; // the next node 
} Node; 
typedef struct list_s { 
    void * head; 
    /* maybe some extra info like size etc */ 
} List; 

Тогда обходе легко:

List * list = malloc(sizeof *list); 
list->head = NULL; 

/* 
    create your first node etc, add to list in the obvious way. 
    ... 
    add more nodes 
    ... 
*/ 

//traversal 
Node ** head = &list->head; 
while (*head) { //we have a non-null node so keep going... 
    Node *cur_node = *head; 
    head = &cur_node->next; 
    /* do stuff with current node (even delete it!). */ 
} 

Таким образом, это очень просто, только два указателя, чтобы беспокоиться о (head и cur_node).