大一新生求救(c语言)
各位前辈,大哥大姐们,我是大一的一位初学者,我遇到一道题,百思不得其解,希望能从前辈们这里得到提示,如果可以的话就把答案打出来,我自己来分析。我真的很需要一位领路人。题目如下:
在当前目录中存在文件名为“file1”的文本文件,其内容为宜篇英文文章(以EOF为结束标志)。现要求读取该文本文件内容,统计文章中美格单词出现的次数,并输出出现次数最多的前5格单词(按出现次数由多到少的顺序输出,次数相同时按字典顺序输出,不足5个单词时,按序输出全部单词)。注意细节如下:
(1)空格,标点符号与回车符起到分隔单词的作用。
(2)名词缩写算一个单词;
(3)单词不分大小写;
(4)输出单词全用小写;
(5)包含多段文字,单词不超10000;没个单词不超20个字符;
(6)数字不算单词;
(7)文件不包含连字符及类似I'm等情况;
(如file1内容如下)
I am astudent.My school is SCAU.It is a beautiful university.I like it.
(在屏幕上输出结果如下)
a 2
i 2
is 2
it 2
am 1
[解决办法]
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <malloc.h>typedef struct node{ char word[21]; int count; struct node *next;}linkNode, *linklist;/**功能:初始化链表*返回值:链表首地址*/linklist initList(){ linklist head; head = (linklist)malloc(sizeof(linkNode)); if(head == NULL) return NULL; head->next = NULL; return head;}/**功能:求链表长度(头结点不计算)*参数:链表首地址*返回值:链表结点数*/int length(linklist head){ int len = 0; if(head == NULL) return 0; head = head->next; while(head != NULL) { ++len; head = head->next; } return len;}/**功能:申请空间*参数:结点(数据)*返回值:指向结点的指针*/linklist makeNode(linkNode nodeData){ linklist newNode; newNode = (linklist)malloc(sizeof(linkNode)); if(newNode == NULL) return NULL; strcpy(newNode->word, nodeData.word); newNode->count = 1; return newNode;}/**功能:输出链表数据*参数:链表首地址*/void printList(linklist head){ if(head == NULL || head->next == NULL) return; head = head->next; while(head != NULL) { printf("%s----%d\n", head->word, head->count); head = head->next; } printf("\n");}/**功能:链表排序(带头结点)*参数:链表首地址**/void listSort(linklist head){ linklist pre, mid, tai; int i, j; int len = length(head); if(head == NULL || head->next == NULL) return; for(i = 0; i < len - 1; ++i) { pre = head; mid = head->next; tai = mid->next; for(j = 0; j < len - i - 1; ++j) { if(mid->count < tai->count || (mid->count == tai->count && strcmp(mid->word, tai->word) > 0)) { pre->next = mid->next; mid->next = tai->next; tai->next = mid; } pre = pre->next; mid = pre->next; tai = mid->next; } }}/**功能:在链表尾部插入结点*参数:链表首地址,待插入结点地址*/void pushBack(linklist head, linklist insertNode){ if(head == NULL) return; while(head->next != NULL) { head = head->next; } head->next = insertNode; insertNode->next = NULL;}/**功能:查找指定结点*参数:链表首地址,结点地址*返回值:找到返回1*没有找到返回-1*/int searchNode(linklist head, linklist findNode){ if(head == NULL || findNode == NULL) return -1; head = head->next; while(head != NULL) { if(strcmp(head->word, findNode->word) == 0) { ++head->count; return 1; } head = head->next; } return -1;}linklist createList(){ linklist list, insertNode; linkNode newNode; FILE *fp; char ch; int i; list = initList(); fp = fopen("file1.txt", "r"); if(fp == NULL) exit(1); i = 0; while(1) { ch = fgetc(fp); if(feof(fp)) { newNode.word[i] = '\0'; break; } if(ch >= 'A' && ch <= 'Z') ch += 32; if(ch == '\n') continue; if(!((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))) { newNode.word[i] = '\0'; if(searchNode(list, &newNode) == -1) { insertNode = makeNode(newNode); pushBack(list, insertNode); } i = 0; } else newNode.word[i++] = ch; } fclose(fp); return list;}int main(){ linklist list; list = createList(); listSort(list); printList(list); return 0;}a----2i----2is----2it----2am----1beautiful----1like----1my----1scau----1school----1student----1university----1统计结果都输出了,要输出前几个,可以修改输出部分
[解决办法]
//简单实现一下,思路很简单 注释的很清楚#include <stdio.h>#include <string.h>#include <ctype.h>#define NUM 20#define COUNT 10000//定义一个结构体来统计单词typedef struct words{ char word[NUM]; int count; //单词出现的次数 }Words;//全局变量Words text[COUNT];int rc = 0; //real_count 实际单词个数 void store(char* word){ int i=0; //判断word是否在text中 int flag = 0; //判断是否是第一个 if(rc==0) { strcpy(text[rc].word,word); text[rc].count = 1; rc++; } else { for(i=0;i<rc;++i) if(strcmp(text[i].word,word)==0) { flag = 1; //text中存在word text[i].count++; //数目增1 break; } if(!flag) { strcpy(text[rc].word,word); text[rc].count = 1; rc++; } }}void swap(Words& from,Words& to){ Words temp; strcpy(temp.word,from.word); temp.count = from.count; strcpy(from.word,to.word); from.count = to.count; strcpy(to.word,temp.word); to.count=temp.count;}//最简单的冒泡排序实现//按照单词出现的次数排序void sortByCount(){ int i,j; for(i=rc-1;i>0;--i) for(j=0;j<i;++j) if(text[j].count<text[j+1].count) swap(text[j],text[j+1]);}void bubbleSort(int n,int m){ int i,j; for(i=n-1;i>0;--i) for(j=m;j<i;++j) if(strcmp(text[j].word,text[j+1].word)==1) swap(text[j],text[j+1]);}//按照单词大小排序void sortByWord(){ int i; int count; int num;//每次排序的个数 int start;//起始位置 for(i=0;i<rc;++i) { count = text[i].count; num = 0; start = i; //统计次数相同的单词个数 while(text[i].count == count) { num++; i++; } bubbleSort(num,start); }}int main(){ char temp[NUM]; int len = 0; char c; FILE * pFile; //打开文件 pFile = fopen ("file1.txt","r"); if (pFile==NULL) perror ("Error opening file"); else { do { c = fgetc (pFile); if (isspace(c) || ispunct(c)) { //字符串结束符为\0 temp[len] = '\0'; len = 0; //将该单词存入text中 store(temp); } else { //不区分大小写 It和it是同一个单词 ,此处进行大小转换 if(isupper(c)) c = c+32; temp[len++] = c; } }while (c != EOF); fclose (pFile); } sortByCount(); sortByWord(); for(int i=0;i<5;++i) { printf("%s %d\n",text[i].word,text[i].count); } return 0;}