2014-08-31 67 views
0

我有一個程序將兩個文件(第一個字表和第二個來自Gutenberg項目的電子書)的字讀入兩個char *數組。將字添加到C中的char * []中

我試圖將第二個char *數組中沒有出現在 第一個char *數組中的所有唯一字添加到第三個char *數組中,然後將它們打印出來。

該程序添加正確的單詞,但不止一次添加它們。 該錯誤發生在findOdds()中。 請注意,當我使用非二進制搜索方法時,此程序正常工作,但需要很長時間。 我的程序有什麼問題?我爲我的英語道歉。

#include <stdio.h> 
#include <stdlib.h> /* for malloc() */ 
#include <ctype.h> 
#include <string.h> 
#define MAXCHAR 24 
#define MAXLINES 150000 

int add2array(FILE *fp, char *lineptr[]); 

int findOdds(char *lineptr[], char *lineptr1[], int nlines, int nlines1); 
int binsearch1(char *val, char *lineptr[], int nlines); 

char *lineptr2[MAXLINES]; /* The unique words not in the word list */ 

int main(int argc, char *argv[]) 
{ 
    FILE *my_stream, *my_stream1; 

    char *lineptr[MAXLINES], *lineptr1[MAXLINES]; 
    int i, nlines, nlines1, nlines2; 

    /* Load the wordlist. */ 
    my_stream = fopen("words.txt","r"); 
    if(my_stream == NULL) { 
     printf("error: Couldn't open file\n"); 
     return 2; 
    } else { 
     nlines = add2array(my_stream, lineptr); 
     fclose(my_stream); 
    } 
    if(nlines==-1) { 
     printf("error: Epic Failure to copy words to char *lineptr[]\n"); 
     return -1; 
    } 

    /* Load the ebook. */ 
    my_stream1 = fopen("horsemanship.txt","r"); 
    if(my_stream1 == NULL) { 
     printf("error: Couldn't open file\n"); 
     return 2; 
    } else { 
     nlines1 = add2array(my_stream1, lineptr1); 
     fclose(my_stream1); 
    } 
    if(nlines1==-1) { 
     printf("error: Epic Failure to copy words to char *lineptr[]\n"); 
     return -1; 
    } 

    /* Find and print the unique words from the ebook not in the wordlist */ 
    nlines2 = findOdds(lineptr, lineptr1, nlines, nlines1); 
    for(i=0; i<nlines2; i++) 
     printf("%s\n",lineptr2[i]); 
    return 0; 
} 

/* add2array: read the words from the file into char *lineptr[] */ 
int add2array(FILE *fp, char *lineptr[]) 
{ 
    int nlines=0, c=0, pos=0; 
    char temp[MAXCHAR]; 
    char *p; 

    while((c = getc(fp)) != EOF) { 
     if(isalpha(c)) 
      temp[pos++] = tolower(c); 
     else if(!isalpha(c)) { 
      temp[pos] = '\0'; 
      pos = 0; 
      if(isalpha(temp[0])){ 
       if((p = malloc(sizeof(temp)))==NULL) 
        return -1; 
       strcpy(p, temp); 
       lineptr[nlines++] = p; 
      } 
     } 
    } 
    return nlines; 
} 

/* Add the unique words from lineptr1 not in lineptr to lineptr2 */ 
int findOdds(char *lineptr[], char *lineptr1[], int nlines, int nlines1) 
{ 
    char *p; 
    char temp[MAXCHAR]; 
    int i, nlines2=0; 

    for(i=0; i<nlines1; i++) { 
     if(binsearch1(lineptr1[i], lineptr, nlines)==-1) { 
      if(binsearch1(lineptr1[i], lineptr2, nlines2)==-1) { 
       if((p = malloc(sizeof(temp)))==NULL) 
        return -1; 
       strcpy(p, lineptr1[i]); 
       lineptr2[nlines2++] = p; 
      } 
     } 
    } 
    return nlines2; 
} 

int binsearch1(char *val, char *lineptr[], int nlines) 
{ 
    int pos; 
    int start = 0; 
    int end = nlines-1; 
    int cond = 0; 

    while(start <= end){ 
     pos=(start + end)/2; 
     if((cond = strcmp(lineptr[pos],val)) == 0) 
      return pos; 
     else if(cond < 0) 
      start = pos+1; 
     else 
      end = pos-1; 
    } 
    return -1; 
} 
+3

由於'MAXLINES'爲'150000',從'binsearch1'返回'666'不是一個很好的「找不到」的指標。返回'-1'是一個更好的指標。 – 2014-08-31 19:42:23

+2

如果要使用二分搜索,則必須對數組進行排序。你的單詞列表是否分類? – 2014-08-31 19:42:43

+0

*爲什麼我沒有想到那個+ Blush *單詞列表已經排序,但我忘記了binsearch的本質,只是添加了第二個文本而沒有使用排序方法。 – lolamontes69 2014-08-31 19:47:20

回答

1

如果您想使用二進制搜索,則必須對數組進行排序,如上面的n.m.所述。

in main() ... 

    shellsort1(lineptr1, nlines1); 
    /* Find and print the unique words from the ebook not in the wordlist */ 
    nlines2 = findOdds(lineptr, lineptr1, nlines, nlines1); 
    ... 


int shellsort1(char *v[], int n) 
{ 
    int gap, i, j; 
    char temp[MAXCHAR]; 
    char *p; 

    for(gap=n/2; gap>0; gap/=2) 
     for(i=gap; i<n; i++) 
      for(j=i-gap; j>=0 && strcmp(v[j],v[j+gap])>0; j-=gap) { 
       if((p = malloc(sizeof(temp)))==NULL) 
        return -1; 
       p = v[j]; 
       v[j] = v[j+gap]; 
       v[j+gap] = p; 
      } 
    return 0; 
}