代码之家  ›  专栏  ›  技术社区  ›  Stelios Papamichail

在qsort中使用strcmp()比较字符串

  •  0
  • Stelios Papamichail  · 技术社区  · 7 年前

    count 田野 obj 中的元素 objArray 在里面 descending order 正如你在下面的程序中所看到的,但我也希望我的程序检查两个电流 objA.count objB.count 中正在使用的字段 cmpfunc() 是相等的,然后检查 objb.word objA.word 字符串,如果是,则交换它们。但是,使用 input.txt 我在下面包含的文件,你可以在输出中看到有东西不工作。你能帮我弄清楚那是什么吗?这个逻辑对我来说似乎是正确的,但也许我误解了 cmpfunc()

    方案c:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    /* PREPROCESSOR */
    #define MAX_STRING_SIZE 512 /* each line in the file can have up to 512 chars */
    
    /* Function Declarations */
    void sortedCount(int,char **);
    void *malloc_or_end(size_t);
    
    
    /* Function Definitions */
    
    /**
     * Allocates sz bytes of memory using malloc, checks if
     * the memory allocation was successfull and return a void* to the
     * beginning of the allocated memory.
     * */
    void* malloc_or_end(size_t sz) {
      void *pointer;
      pointer = malloc(sz);
      if(pointer == NULL) {
        printf("Out of memory, terminating.\n");
        exit(-1);
      }
      return pointer;
    }
    
    /**
     * Function count: Prints the number of times
     * that the selected word is found inside the N first words
     * of the file.
     * */
    int count(int N, char *word, int callID,char **wordList) {
        int i = 0;
        int count = 0;
        for(i = 0; i < N; i++) {
            if(strcmp(word,wordList[i]) == 0) {
                count++;
            }
        }
        if(callID == 0) { /* if callID == 0 (main called count and we want the output) */
            printf("%d",count);
            printf("\n");
        }
        return count;
    }
    
    typedef struct wordAndCount {
        int count;
        char *word;
    } obj;
    
    int cmpfunc(const void * a, const void * b) {
        obj objA = *(obj *)a;
        obj objB = *(obj *)b;
        int res = objA.count - objB.count;
    
        if(res > 0) {
            return -1;
        } else if(res < 0) { /* 2nd count is greater than the first */
            return 2;
        } else {
            int cmpResult = strcmp(objB.word,objA.word);
            if(cmpResult > 0) {
            } else if(cmpResult < 0) {
                /* do nothing */
                char *temp = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
                strcpy(temp,objA.word);
                strcpy(objA.word,objB.word);
                strcpy(objB.word,temp);
                free(temp);
            } else {
                /* do nothing */
            }
            return 0;
        }
    }
    
    void sortedCount(int N,char **wordList) {
        int i,j = 0;
        int *occurrences;
        obj *objArray;
    
        /* mem allocation */
        objArray = malloc_or_end(N * sizeof(obj));
        occurrences = malloc_or_end(N * sizeof(int));
    
        /* initialize occurrences for the "each word is unique and occurs only once" scenario */
        for(i = 0; i < N; i++) {
            objArray[i].word = malloc_or_end(MAX_STRING_SIZE * sizeof(char));
            occurrences[i] = 1;
        }
    
        determineUniqueWords(occurrences,wordList,N);
    
        /* populate the wordCounts & uniqueWords "arrays" with the appropriate data in order to sort them successfully */
        for(i = 0; i < N; i++) {
            if(occurrences[i] > 0) {
                objArray[i].count = count(N,wordList[i],1,wordList);
                strcpy(objArray[i].word,wordList[i]);
            }
        }
    
        /* sort */
        qsort(objArray,N,sizeof(obj),cmpfunc);
    
        for(i = 0; i< N; i++) {
            if(objArray[i].count == 0 || (strcmp(objArray[i].word,"") == 0)) {
                continue;
            }
            printf("%d %s\n",objArray[i].count,objArray[i].word);
        }
    
        /* mem free */
        for(i = 0; i < N; i++) {
            free(objArray[i].word);
        }
        free(objArray);
        free(occurrences);
        return;
    }
    
    /* Stelios Papamichail AM 4020 */
    int main(int argc,char *argv[]) { /* argv[1] = op argv[2] = name argv[3] = <word> */
        int N = -1;
        int i = 0;
        int spaceNum,nlNum = -1;
    
        FILE *file; 
        char **wordList; 
    
    
        file = fopen(argv[2],"r");
    
        if(file == (FILE *) NULL) { /* check if the file opened successfully */
            fprintf(stderr,"Cannot open file\n");
        }
    
        fscanf(file,"%d",&N); /* get the N number */
    
        wordList = malloc_or_end(N * sizeof(char *)); /* allocate memory for pointers */
    
        for(i = 0; i < N; i++) {
            wordList[i] = malloc_or_end(MAX_STRING_SIZE * sizeof(char)); /* allocate memory for strings */
        }
    
        populateWordsArray(N,wordList,file);
    
        if(strcmp(argv[1],"-reverse") == 0) {
            reverse(N,wordList);
        } else if(strcmp(argv[1],"-first") == 0) {
            first(N,wordList);
        } else if(strcmp(argv[1],"-middle") == 0) {
            middle(N,wordList);
        } else if(strcmp(argv[1],"-last") == 0) {
            last(N,wordList);
        } else if((strcmp(argv[1],"-count") == 0) && argv[3] != NULL) {
            i = count(N,argv[3],0,wordList);
        } else if((strcmp(argv[1],"-sorted") == 0) && (strcmp(argv[3],"-count") == 0)) {
            sortedCount(N,wordList);
        } else {
            /* i only wish i could print something here */
        }
    
    
        /* End of program operations */
        for(i = 0; i < N; i++) {
            free(wordList[i]);
        }
        free(wordList);
        fclose(file);
        return 0;
    }
    

    Input.txt:

    11 this is a simple text is a a z z z
    

    输出:

    3 a
    3 z
    2 is
    1 simple
    1 text
    1 this
    

    预期产出:

    3 z
    3 a
    2 is
    1 simple
    1 this
    1 text
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Gerhardh    7 年前

    您的比较函数不应操纵被比较的对象。 您只能返回比较结果:

    int cmpfunc(const void * a, const void * b)
    {
        obj *objA = (obj *)a;
        obj *objB = (obj *)b;
    
        int res = objA->count - objB->count;
        // negative value means A is less than B.
    
        if(res == 0)
        {
            res = strcmp(objA->word, objB->word);
            // negative value if A is less than B.
        }
    
        return res; // or -res for other sorting direction
    }
    

    当您可以使用指针直接在数组中访问元素时,也不需要复制函数中的元素。