2017-12-10 5 views
0

내 프로그래밍 물론 내 코드를 마무리하는 몇 가지 문제에 봉착와 정렬 된 링크 목록 (I는 C에서 절대 초보자 해요). 목적은, 표준 입력 (< input.c 런 파일) 단어를 읽어들이 주파수를 계산하고 (제 1 대문자 단어)을 알파벳순으로리스트를 분류하는, 예를 들어 출력 :C - 단어와 주파수

Image Sample output

은 여기 코드 조각 발견 스택에 적용했는데, 지금까지 단어와 빈도가있는 출력을 생성합니다. 그러나, 나는 위의 샘플에서 정렬 된 목록을 가져 오는 방법을 알아낼 수 없습니다. 나는 마찬가지로 지금까지

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

: 우리 선생님은 새로운 단어가 발견되면, 그것은 바로 연결리스트로 분류 삽입 할 것을 제안, 그가 우리에게 다음 코드 샘플을 주었다 (이 this program에서 발췌 한 것입니다) '링크 * n'은 다음 노드에 대한 포인터 여야하며 '데이터'는이 경우 정수를 보유하고 '죄수'는이 코드에서 새 노드 또는 링크를 구성하는 함수 여야하며 ' 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

음, "코드 샘플은"완전한 헛소리입니다. 아주 좋은 의사 코드조차도 아닙니다. 다른 데이터를 기준으로 데이터를 정렬하려면 데이터를 비교할 방법이 있어야합니다. 링크 된 목록의 경우, 두 노드 사이에 또는 마지막 노드 다음에 새 노드를 삽입합니다. –

+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); 
    } 
} 

다른 점 몇 가지 : 당신은 31 문자 버퍼를 가지고,하지만 당신은 당신의 readWord 기능을 말하는 것

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

이 그것을 10K 문자입니까? 또한

malloc()에서 반환 값을 캐스팅하지 않습니다.

+0

고마워요! 그들은 그대로 사용할 수는 없지만 코드에 빠진 몇 가지 사항을 분명히 포함하고 있습니다. 내 construct() 및 addWord() 함수를 다시 작성할만큼 충분합니다. 지금대로 작동해야합니다! 버퍼와 크기에 대해서는 정확하게 설명 할 수 없으므로 각 단어에 최대 버퍼를 설정하고 목록의 최대 크기를 설정하는 것이 좋습니다. 따라서 프로그램이 여러 연령대로 실행되지 않습니다. 단어와 연결된 목록을 사용하는 여러 코드에서 발견되면이 코드를 다시 사용했습니다. – Ben