SCAU 高程綜合實驗:檔案操作與字元處理
SCAU 高程綜合實驗:檔案操作與字元處理
在當前目錄中存在檔名為"case1.in"(其中case後為數字1,不是字母l,寫錯提交後會判錯)的文字檔案,
其內容為一篇英文文章(以EOF作為結束標誌)。現要求讀取該文字檔案內容,統計文章中每個單詞出現的次數,
並輸出出現次數最多的前5個單詞及其出現次數(按出現次數由多到少的順序輸出,次數相同時按字典順序輸出,
不足5個單詞時,按序輸出全部單詞)。程式中注意如下細節:
(1) 空格、標點符號與回車符起到分隔單詞的作用。
(2) 文章一行的末尾可能有連字元,出現連字元時,該行最末的字串與下行最先出現的字串構一個單詞;
(3) 名詞縮寫算一個單詞;
(4) 數字不算單詞;
(5) 單詞不區分大小寫;
(6) 輸出時單詞全使用小寫;
#include “stdio.h”
#include “math.h”
#include “string.h”
#include “stdlib.h”
main()
{
_______________________
}
輸入格式
檔案case1.in中一篇英文文章,包含多段文字,單詞數不超過10000,每個單詞不超過20個字元
輸出格式
按題意輸出答案
輸入樣例
(如case1.in內容如下)
I am a student. My school is SCAU. It is a beau-
tiful university. I like it.
輸出樣例
a 2
i 2
is 2
it 2
am 1
解題思路分析:
按照解題順序,分析一下幾個重要的點:
第一個考點是檔案操作,檔案的開啟關閉和讀寫。題目中說掃描單詞,又由於有字串的特殊要求,所以使用fscanf有點小困難,還是使用fgetc逐字掃描、判斷。
第二個考點是單詞的判斷,也是這道題的核心,這個和前面oj上一題對單詞的判斷讀寫幾乎相同,只是多了個連字元的問題。當掃描到有單詞結束的符號(空格、標點等),打上標記,有連字元+換行的話,另作標記。
第三個考點是字串的存放以及字串的排序,當然其中也不可避免的有string庫中函式的運用。由於掃描完單詞後便存入陣列,自然要用到字串陣列,其中也變相的考察了學生地址(指標)的概念。排序的話自然是字典序,由於能力有限,使用冒泡+strcpy進行排序。
下面貼一下我的程式碼(含詳註)。
#include "stdio.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
char sto[10005][25];//字串陣列,無重複
int num=0;//字串陣列下標
int count[10005]; //每個單詞出現的次數
int isalpha(char ch) //判斷是否為字母(函式庫裡竟然沒有isalpha)
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) return 1;
else return 0;
}
int repeat(char *s)//判斷單詞是否重複
{
int i;
for(i=0;i<num;i++)
{
if(!strcmp(sto[i],s))//查重
{if(i==0) return 20000;else return i;}//查到重複的單詞,則返回單詞第一次出現的下標
}
return 0;//沒查到,則返回0
}
main()
{
FILE *fp;
int i,j=0,k;
char ch;
int endflag=0,lianflag=0,enter=0;
for(i=0;i<10005;i++) count[i]=1;//計數器初始化為1
fp=fopen("case1.in","r+");//開啟檔案
if(fp==NULL) {printf("ERROR");return 0;}
while((ch=fgetc(fp))!=EOF)//由於有連字元,用fscanf有點困難,所以開始逐字掃描操作,
{
if(isalpha(ch)&&ch>='A'&&ch<='Z') ch+=32;
if(isalpha(ch)&&endflag&&!lianflag&&!enter) {enter=0;endflag=0;lianflag=0;j=0;num++;sto[num][j++]=ch;}//新單詞的情況,更新連字元、回車、單詞結束的標記,建立新一行陣列記錄下一個單詞
else if(isalpha(ch)&&endflag==0&&!lianflag&&!enter) {enter=0;lianflag=0;sto[num][j++]=ch;}//同一個單詞的情況,即單詞續寫
else if(ch==' '||(lianflag==0&&ch=='\n')||((ch!='-')&&((ch>=32&&ch<=47)||(ch>=49&&ch<=64)||(ch>=91&&ch<=96)||(ch>=123&&ch<=126))))//單詞結束,檢索到符號、換行,就換單詞
{
enter=0;endflag=1;lianflag=0;
int p=0;
if(p=repeat(sto[num])) {if(p==20000) p=0;memset(sto[num],0,sizeof(sto[num]));num--;count[p]++;}
}
else if(isalpha(ch)&&lianflag&&!enter)//有連字元但無回車的特殊情況,算新單詞的出現,也標誌著連字元前一個單詞的結束,對前一個單詞進行查重計數,然後進行新單詞建立的操作
{int p=0;
if(p=repeat(sto[num])) {if(p==20000) p=0;memset(sto[num],0,sizeof(sto[num]));num--;count[p]++;}
enter=0;endflag=0;lianflag=0;j=0;num++;sto[num][j++]=ch;
}
else if(ch=='-'&&endflag==0) {enter=0;lianflag=1;}//檢索到連字元標記一下
else if(ch=='\n') {enter=1;}//檢索到換行標記一下
else if(lianflag&&isalpha(ch)&&!endflag&&enter) {enter=0;lianflag=0;sto[num][j++]=ch;}//有連字元+回車的情況,是原來的單詞,進行單詞的續寫
else {endflag=1;lianflag=0;if(repeat(sto[num])) {memset(sto[num],0,sizeof(sto[num]));num--;count[repeat(sto[num])]++;}} //其餘情況(包括數字)算作無單詞,進行標記的清除
}
fclose(fp);//檔案掃描結束,關閉檔案
char t[25];//下面將用到冒泡,建立第三方變數
int t2=0;//同理,計數器也要用到冒泡
for(i=0;i<num-1;i++)//將字串陣列按照字典序排序,使用氣泡排序
for(j=0;j<num-1-i;j++)
if(strcmp(sto[j],sto[j+1])>0)
{memset(t,0,sizeof(t));strcpy(t,sto[j]);t2=count[j];strcpy(sto[j],sto[j+1]);count[j]=count[j+1];strcpy(sto[j+1],t);count[j+1]=t2;}
int p=0;//掃描次數前五的單詞,如果不足五個就直接return 0
int max1=0,max2=0,max3=0,max4=0,max5=0; //由於只有五個,就不對次數進行排序了,直接比較依次求最多次數就好,比完把最多的次數清零
for(i=0;i<=num;i++) if(max1<count[i]) {p=i;max1=count[i];}
count[p]=0;
printf("%s %d\n",sto[p],max1);
for(i=0;i<=num;i++) if(max2<count[i]) {p=i;max2=count[i];}
if(max2==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max2);
}
for(i=0;i<=num;i++) if(max3<count[i]) {p=i;max3=count[i];}
if(max3==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max3);
}
for(i=0;i<=num;i++) if(max4<count[i]) {p=i;max4=count[i];}
if(max4==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max4);
}
for(i=0;i<=num;i++) if(max5<count[i]) {p=i;max5=count[i];}
if(max5==0) return 0;
else
{
count[p]=0;
printf("%s %d\n",sto[p],max5);
}
return 0;
}
總結與心得:
綜合性實驗主要考查本學期c語言所學語法的綜合運用,靈活多變,思維量不大,實驗過程中細節和注意點較多。
儘管實驗大體思路清晰,但是在我的實踐過程並不是一帆風順。一開始沒有注意題目中連字元的規定,用了fscanf,看到測試資料t-t-t-t人傻了(這貨算4個單詞???),然後從零開始。很多知識點的細節沒徹底瞭解,也增添了我程式中的小bug。
通過本次實驗,我明白了平時學習知識,除了重點練習知識點主體部分,許多細節和注意點也要多多留意。題目先看清看完整,大體思路想明白寫清楚,再動手敲程式碼。有錯就改,改錯也是學知識不可或缺的一個環節,也是完善知識的一個過程,許多問題也是在上機實踐過程中才發現自己不會寫,然後通過搜尋引擎或者和小夥伴、老師的討論交流,去補上自己知識層面的漏洞或者改善自己程式碼。
相關文章
- 字元編碼與檔案處理字元
- Go檔案操作綜合指南Go
- Python批處理:檔案操作Python
- 綜合實驗
- OSPF 綜合實驗
- OSPF綜合實驗
- BGP綜合實驗
- day07.檔案操作/綜合應用【Python教程】Python
- 07 Windows批處理之檔案操作Windows
- 資料匯入與預處理實驗二---json格式檔案轉換JSON
- C++ 字元處理函式(cctype標頭檔案)C++字元函式
- 實時流處理與分散式儲存過程中對檔案的操作分散式儲存過程
- 靜態路由綜合實驗路由
- IO流之 檔案操作字元流字元
- django-驗證碼/靜態檔案處理Django
- 綜合實驗,策略路由(BFD,NAT)路由
- 靜態路由及綜合實驗路由
- GC機制+字元編碼+檔案操作GC字元
- python 檔案處理Python
- python處理檔案Python
- python檔案處理Python
- Linux備份任務綜合實驗Linux
- C檔案與檔案的操作
- python處理txt檔案Python
- window 批處理檔案
- Python之檔案處理Python
- Go xml檔案處理GoXML
- IDA批量處理VirusShare樣本獲得asm檔案與bytes檔案ASM
- 從零手寫實現 nginx-11-檔案處理邏輯與 range 範圍查詢合併Nginx
- 資料結構實驗三:線性表綜合實驗資料結構
- Linux----12 檔案與檔案操作Linux
- 010.OpenShift綜合實驗及應用
- 使用無伺服器實現檔案處理的批處理 - DZone Cloud伺服器Cloud
- Python編解碼問題與文字檔案處理Python
- node js 處理PDF檔案JS
- 控制檔案損壞處理
- python ini 配置檔案處理Python
- Python如何處理檔案的?Python