2017-12-10 12 views
0

プログラミングコースのコードを完成させるためにいくつかの問題があります(私はC言語の初心者です)。目的は、標準入力から(< input.c RUNFILE)の言葉を読んでその頻度をカウントし、(最初の大文字の単語を)リストをアルファベット順にソートすることで、出力例:C - ソートされた単語と頻度のリンクリスト

Image Sample output

は、私はここでのコードの断片を発見しました私が適応したスタック上のスタックであり、これまでは単語とその頻度で出力を生成しています。しかし、私は上のサンプルのようにソートされたリストを取得する方法を理解できません。 I限り

void addSorted(link *n, int x) { 
    if (*n == NULL || x < (*n)->data) { 
    *n = cons(x, *n); 
    } else { 
    addSorted(&((*n)->next), x); 
    } 
} 

:私たちの先生は新しい単語が見つかった場合、それはすぐにリンクされたリストにソート挿入する必要があることを示唆している、彼は私たちに次のコードサンプルを与えた(それはthis programからの抜粋です) 'link * n'は次のノードへのポインタでなければならず、 'data'はその場合整数を保持していて、 'cons'は新しいノードやリンクを構築するためにこのコード内の関数でなければなりません。 int x '、私の推測それは比較のための現在の整数です。 私が言ったように、私はこの最後のビットを自分のコードに適合させるのに問題があります。私は私のaddWord()関数に適応しようとしましたが、それは私のためにはうまくいきません。すべてのヘルプは高く評価され

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

//=============== STRUCTURE ================== 
typedef struct word { 
    char *mywords;    // list node with word pointer 
    int freq;     // Frequency count 
    struct word *pNext;   // Pointer to next node in linked list 
    } Word; 

//======= INITIATION OF FUNCTIONS =========== 
int readWord(char *temp_word, int temp_size); // Given function to get words 
void addWord(char *pWord);      // Adds a word to the list or updates exisiting word 
void printmywords(Word *pListNodes);   // Output list of words and frequencies 
Word* construct(char *word);     // Constructs list nodes 

//============GLOBAL VARIABLES================ 
Word *pFirst = NULL;     // Pointer to first node in linked list 

//================ MAIN ======================  
int main() { 

    char temp_word[32]; // temporary buffer to hold words 
    int size = 10000; 

    Word *pNode = NULL; // pointer to word counter 

    while (readWord(temp_word, size)) { // Read all words from standard input 

     addWord(temp_word); // Add word to list 
    } 

    // List the words and their counts 
    pNode = pFirst; 
    while(pNode != NULL) 
    { 
     printmywords(pNode); 
     pNode = pNode->pNext; 
    } 
    printf("\n"); 

    // Free the allocated memory 
    pNode = pFirst; 
    while(pNode != NULL) 
    { 
     free(pNode->mywords);   
     pFirst = pNode;   
     pNode = pNode->pNext; 
     free(pFirst);     
    } 
    return 0; 
} 

//================ FUNCTIONS ================= 

void printmywords(Word *pListNodes) 
{ 
    printf("\n%-20s %5d", pListNodes->mywords,pListNodes->freq); // output word and frequency 
} 

void addWord(char *word) 
{ 
    Word *pNode = NULL; 
    Word *pLast = NULL; 

    if(pFirst == NULL) 
    { 
    pFirst = construct(word); 
    return; 
    } 

    // Update frequency, if word in list 
    pNode = pFirst; 
    while(pNode != NULL) 
    { 
    if(strcmp(word, pNode->mywords) == 0) 
    { 
     ++pNode->freq; 
     return; 
    } 
    pLast = pNode;    
    pNode = pNode->pNext; 
    } 

    // Add new word, if not in list 
    pLast->pNext = construct(word); 
} 

Word* construct(char *word) 
{ 
    Word *pNode = NULL; 
    pNode = (Word*)malloc(sizeof(Word)); 
    pNode->mywords = (char*)malloc(strlen(word)+1); 
    strcpy(pNode->mywords, word); 
    pNode->freq = 1; 
    pNode->pNext = NULL; 
    return pNode; 
} 

int readWord(char *temp_word, int temp_size) { 
    char *p = temp_word; 
    char c; 

    // skip all non-word characters 
    do { 
     c = getchar(); 
     if (c == EOF) 
      return 0; 
     } while (!isalpha(c)); 

    // read word chars 
    do { 
     if (p - temp_word < temp_size - 1) 
     *p++ = c; 
     c = getchar(); 
     } while (isalpha(c)); 

     // finalize word 
     *p = '\0'; 
     return 1; 
     } 

:あなた以下 は、私がこれまで持って動作するコードを見つけます。

+0

まあ、 "コードサンプル"は完全なばかげたものです。非常に良い擬似コードでもありません。データを他のデータとの関連でソートする場合は、それらを比較する方法が必要です。リンクされたリストの場合は、2つのノードの間に新しいノードを挿入するか、最後のノードの後に​​新しいノードを挿入します。 –

+0

はい、申し訳ありませんがサンプルコードは、私はソースコードへの説明とリンクを追加しました、私はそのビットを明確にすることを願っています。そのサンプルプログラムは、ソート時に整数を互いに比較します。私はそれが少し楽だと思います。 私の場合、strcmp()のようなものを使うべきかどうか疑問に思っていますか? – Ben

+0

ねえ、それを見てください。 –

答えて

0

さて、これら二つの機能を試してみてください。

Word *cons(char *word, Word *next) { 
    Word *result = construct(word); 
    if (result) { 
    result->pNext = next; 
    } 
    else { 
    printf("Out of memory in cons\n"); 
    exit(1); 
    } 
    return result; 
} 

void addSorted(Word **nodeRef, char *word) { 
    Word *node = *nodeRef; 

    /* strcmp will do a binary comparison, which suits your purpose 
    because you want capitalized words before lower-case; the order 
    of the arguments is important - <0 means the first argument should 
    come before the second argument. */ 

    if ((node == NULL) || (strcmp(word, node->mywords) < 0)) { 
    *nodeRef = cons(word, node); 
    } 
    else if (strcmp(word, node->mywords) == 0) { 
    ++node->freq; 
    } 
    else { 
    /* there's not really any point to using recursion on a linked 
     list, except for the fact that it's really easy to use recursion 
     on a linked list. On a vary large list, iteration would most likely 
     be faster; however, professors really like to show how clever they 
     are, so you're better off using it anyway. */ 

    addSorted(&node->pNext, word); 
    } 
} 

他のポイントのカップル:

char temp_word[32]; // temporary buffer to hold words 
int size = 10000; 

あなたは31文字バッファを持っていますが、それことをあなたのreadWord機能を言っています10K文字ですか?

また、戻り値をmalloc()からキャストしないでください。

+0

ありがとう!それらをそのまま使用することはできませんでしたが、私のコードでは欠落していた点があります。 constructor()とaddWord()関数を書き換えるのに十分です。それは今通りに動作します! バッファとサイズに関しては、正確には説明できません。各単語の最大バッファーとリストの最大サイズを設定することが推奨されているので、プログラムは何年も実行されません。単語やリンクされたリストを扱ういくつかのコードで見つかったので、私はこれを再利用していました。 – Ben

関連する問題