C - отсортированный связанный список со словами и частотами
У меня есть некоторые проблемы при завершении моего кода для курса программирования (я абсолютный новичок в Си). Цель состоит в том, чтобы прочитать слова из стандартного ввода (runfile Здесь, в стеке, я нашел фрагменты кодов, которые я адаптировал, и до сих пор он выводит слова и их частоты. Тем не менее, я не могу понять, как отсортировать список, как в примере выше. Наш учитель предлагает, чтобы, если новое слово было найдено, оно было вставлено и сразу отсортировано в связанный список, он дал нам следующий пример кода (это отрывок из этой программы): Насколько я понимаю, "link *n" должен быть указателем на следующий узел, "data" в этом случае содержит целые числа, а "cons" должна быть функцией в этом коде для создания нового узла или ссылки, не уверен насчет 'int x', я думаю, это текущее целое число для сравнения. Как я уже сказал, у меня проблемы с адаптацией этого последнего бита в мой код. Я пытался адаптировать свою функцию addWord(), но у меня ничего не вышло. Ниже вы найдете рабочий код, который у меня есть: Любая помощь приветствуется.void addSorted(link *n, int x) {
if (*n == NULL || x < (*n)->data) {
*n = cons(x, *n);
} else {
addSorted(&((*n)->next), x);
}
}
#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;
}
1 ответ
Хорошо, попробуйте эти две функции:
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
функция что это 10К символов?
Кроме того, не приводите возвращаемое значение из malloc()
,