2013-05-25 3 views
0

я в настоящее время этот алгоритм:C - Объединение двух списков строк

char** mergeLists(char **a, char **b, int sizeA, int sizeB, int *lSize) 
{ 
    char **list = malloc(sizeof(char *)); 
    int pA = 0, pB = 0, listSize = 0; 

    while (pA != sizeA && pB != sizeB) 
    { 
     list = realloc(list, sizeof(char *) * (++listSize)); 

     if (strcmp(a[pA], b[pB]) < 0) 
     { 
      list[listSize-1] = a[pA]; 
      pA++;     
     } 
     else 
     { 
      list[listSize-1] = b[pB]; 
      pB++; 
     }  
    } 

    *lSize = listSize; 

    return list; 
} 

Но, кажется, есть некоторые ошибки. Я в настоящее время работает этот тест:

char *l1[6]; 
l1[0] = "a"; 
l1[1] = "b"; 
l1[2] = "c"; 
l1[3] = "d"; 
l1[4] = "e"; 
l1[5] = "f"; 

char *l2[6]; 
l2[0] = "aa"; 
l2[1] = "ba"; 
l2[2] = "ca"; 
l2[3] = "da"; 
l2[4] = "ea"; 
l2[5] = "fa"; 

int s; 
char **l = mergeLists(l1, l2, 6, 6, &s); 

int i = 0; 
for(i = 0; i < s; i++) 
    printf("%s\n", l[i]); 

Это печать:

a 
aa 
b 
ba 
c 
ca 
d 
da 
e 
ea 
f 

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

Я был бы признателен за помощь. Спасибо.

+3

Кроме того, вы знаете, как большой массив назначения должен быть. Не нужно «malloc», а затем 'realloc' каждый раз ...! –

+2

Это не источник вашей ошибки, но вы действительно должны использовать 'size_t' для длин массивов, длины строк, индексы массивов, размеры объектов, все, что вы планируете передать в' malloc', или получить от 'sizeof' и' strlen' , –

+0

Я не уверен на 100%, я бы назвал это слияние двух * списков * строк, но двух массивов * строк. Помимо этого, ответ уже предоставлен. – Vatine

ответ

6

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

+0

Что делать, если я изменяю условие while while (pA! = SizeA || pB! = SizeB)? Я уже пробовал это, но pA достигает значения 7 и есть segfault ... – rafaame

+2

Вам нужно будет дополнить условия внутри цикла, чтобы искать исчерпание одного из списков. –

1

исправить так:

char** mergeLists(char **a, char **b, int sizeA, int sizeB, int *lSize){ 
    char **list = NULL; 
    int pA = 0, pB = 0, listSize = 0; 
    int emptyA = 0, emptyB = 0; 

    while (pA != sizeA || pB != sizeB){ 
     list = realloc(list, sizeof(char *) * (++listSize)); 

     if(emptyA){ 
      list[listSize-1] = b[pB++]; 
      continue; 
     } 
     if(emptyB){ 
      list[listSize-1] = b[pA++]; 
      continue; 
     } 
     if (strcmp(a[pA], b[pB]) < 0){ 
      list[listSize-1] = a[pA++]; 
      if(pA == sizeA) 
       emptyA = 1; 
     } 
     else{ 
      list[listSize-1] = b[pB++]; 
      if(pB == sizeB) 
       emptyB = 1; 
     } 
    } 

    *lSize = listSize; 

    return list; 
} 
1
#include <stdlib.h> 
#include <string.h> 

char **merge_arrays(char **arrA, char **arrB, size_t sizeA, size_t sizeB, size_t *lSize) 
{ 
    size_t idxA , idxB , idxDst ; 
    char **result ; 

    result = malloc((sizeA+sizeB) * sizeof *result); 
    if (!result) return NULL; 

    for(idxA=idxB=idxDst=0; idxA < sizeA && idxB < sizeB;) 
    { 
     if (strcmp(arrA[idxA], arrB[idxB]) <= 0) result[idxDst++] = arrA[idxA++]; 
     else result[idxDst++] = arrB[idxB++]; 
    } 

    if (idxA < sizeA) { 
     memcpy (result+idxDst, arrA+idxA, (sizeA-idxA) * sizeof *result); 
     idxDst += sizeA-idxA; 
     } 
    else if (idxB < sizeB) { 
     memcpy (result+idxDst, arrB+idxB, (sizeB-idxB) * sizeof *result); 
     idxDst += sizeB-idxB; 
     } 

    *lSize = idxDst; 

    return result; 
} 
Смежные вопросы