首页 > 编程语言 >文件操作与字符处理_综合性报告(华南农业大学_高级程序语言设计)

文件操作与字符处理_综合性报告(华南农业大学_高级程序语言设计)

时间:2024-07-30 19:53:55浏览次数:14  
标签:字符 华南农业大学 re int ++ 单词 程序语言 char chuan

华南农业大学的同学们,看到这里估计你们是不会/没时间写综合性实验了。

我这里给你们提供一些思路和个人见解,希望你们能顺利完成这道题目咯。加油加油!

【本文章仅供学习使用,未经允许禁止转载】

1.题目&要求

文件操作与字符处理_综合性报告

在当前目录中存在文件名为"case1.in"(其中case后为数字1,不是字母l,写错提交后会判错)的文本文件,其内容为一篇英文文章(以EOF作为结束标志)。现要求读取该文本文件内容,统计文章中每个单词出现的次数,并输出出现次数最多的前5个单词及其出现次数(按出现次数由多到少的顺序输出,次数相同时按字典顺序输出,不足5个单词时,按序输出全部单词)。程序中注意如下细节:

(1) 空格、标点符号与回车符起到分隔单词的作用。

(2) 文章一行的末尾可能有连字符,出现连字符时,该行最末的字符串与下行最先出现的字符串构一个单词;

(3) 名词缩写算一个单词;

(4) 数字不算单词;

(5) 单词不区分大小写;

(6) 输出时单词全使用小写;

2.源代码

话不多说,先贴源代码

#include "stdio.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
 
#include <ctype.h>
int t=0;
int mem; 
struct wo{
	char word[21];
	int num;
}re[10000];
int jud(char test[])
{
	int i=0;
	for(i=0;i<t;i++)
		if(strcmp(test,re[i].word)==0)
		{
			re[i].num++;
			mem=i;
			return 0;
		}	
	return 1;
}
int ret(char chuan[],int i)
{
	int judd=0;
	char *a=&chuan[i];
	while(!isalpha(*a))
	{
		if(*a=='\0') return i+(a-&chuan[i])-1;
		a++;
	}
	char *b=a;
	while(isalpha(*b))
		b++;
	char tem[21];
	int q=0,w=0;
	for(q=0;a!=b;a++,q++)
		tem[q]=*a;
	tem[q]='\0';
	char tem2[21];
	memset(tem2,0,sizeof(tem2));
	if(*a=='-' && *(a+1)=='\n' && isalpha(*(a+2)))
	{
		while(!isalpha(*a))
			a++;
		b=a;
		while(isalpha(*b))
			b++;
		for(q=0;a!=b;a++,q++)
			tem2[q]=*a;
		tem2[q]='\0';
	}
	char *ttem=strcat(tem,tem2);
	if(jud(ttem)==1)
	{
		for(w=0;w<sizeof(tem);w++)
			re[t].word[w]=ttem[w];
		re[t].word[w]='\0'; 
		re[t].num=1;
		mem=t;
		t++;
	}
	if(*b=='\0') return i+(b-&chuan[i])-2;
	return i+(b-&chuan[i])-1;
}
 
main()
{
    FILE *fp;
	fp=fopen("case1.in","r");
	char ch,chuan[100000];
	int n_max;
	for(n_max=0;(ch=fgetc(fp))!=EOF;n_max++)
		chuan[n_max]=tolower(ch);
	chuan[n_max]=0;
	int i=0,j=0,time=0;
	char *st=chuan,*en=chuan;
	for(i=0;i<n_max;i++)
		i=ret(chuan,i);
	for(i=0;i<5;i++)
	{
		int k=i;
		for(j=i+1;j<t;j++)
			if((re[k].num<re[j].num)||(re[k].num==re[j].num&&strcmp(re[k].word,re[j].word)>0))
				k=j;
		struct wo a =re[k];
		re[k]=re[i];
		re[i]=a;
	}
	for(i=0;i<5;i++)
		printf("%s %d\n",re[i].word,re[i].num);
	fclose(fp);
}

3.带注释代码

#include "stdio.h"
#include "math.h"
#include "string.h"
#include "stdlib.h"
 
#include <ctype.h>
//这个头文件呢适用于文本处理
//里面的函数比较方便
//感兴趣的可以了解一下 
 
int t=0;							//全局变量,用于记录单词的种类数量
 
int mem;							//【没用,忘删了】 
 
struct wo{							//我把结构数组的声明放在这里 
	char word[21];					//目的是是这个结构数组成为全局变量
	int num;						//让任何一个函数都可以直接访问和修改里面的元素 
}re[10000];
									
									 
//jud函数,返回整型变量,需要传递一个(待测试的)字符串
//用于判断某个单词是否已经出现 
int jud(char test[])
{
	int i=0;
	for(i=0;i<t;i++)						//遍历结构数组 
	{
		if(strcmp(test,re[i].word)==0)		//假如已出现过该字符串 
		{
			re[i].num++;					//该字符串对应的出现数量+1 
			mem=i;							//【没用,忘删了】 
			return 0;						//返回0代表不需要新增结构体 
		}
	}	
	return 1;								//返回1代表该单词未出现过
											//需要新增结构体 
}
 
//ret函数,返回整型变量 
//用于整理字符串中的单词,放入结构数组中 
int ret(char chuan[],int i)
{
	int judd=0;
	
	//第一部分 
	char *a=&chuan[i];		//我习惯用指针,当然用下标数字也可以,也许更好写一点 
 
							//isaipha(int)
							//这个函数用于判断括号里面的字符是否为英文字母(不论大小写)
							//如果是字母,就返回1/真;如果不是,就返回0/假 
							//但在这里,我前面加了一个感叹号“!”,代表否 
	while(!isalpha(*a))		//说明如果函数返回真,则为假...(学过计导计概的都会吧) 
	{
		if(*a=='\0')
		{											//这里防止检测到字符串结尾
			return i+(a-&chuan[i])-1;				//如果是就直接返回字符串结尾...的上一个字符的下标
		}											//注意!为什么可以直接返回呢 ? 
													//因为条件决定了如果是字母就不可能进入循环体 
													//一旦进入循环体了,那就说明前面没有检测到字母 
		
		a++;										//如果不是就指针指向下一位字符 
	}												//注意!循环结束后a位于单词的开始 
	
	char *b=a;										//这里是已经检测到一个“单词”存在了 
													//a指针是一个单词的开始
													//那我复制一下a指针
													 
	while(isalpha(*b))								//这个循环用于找到单词的末尾 
	{												//注意!为什么这里不需要上一个循环的判断语句? 
		b++;										//因为这个字符串的结尾是空字符,一定不是字母 
	}												//所以不用担心这回事
													//注意!循环结束后b位于单词的末尾的后一个字符 
	
	char tem[21];									//声明了一个字符串用来放这个单词 
	int q=0,w=0;
	for(q=0;a!=b;a++,q++)							//放单词的过程 
		tem[q]=*a; 									//在这个循环结束后,a到了b的位置
													//也就是单词的后一个字符 
	tem[q]='\0';									//不要忘了以空字符结尾 
	
	//第二部分 
	char tem2[21];									//创建一下第二个放单词的字符串 
	memset(tem2,0,sizeof(tem2));					//这个函数在stdlib.h里面,用于刷新数组
													//这一步相当于初始化,tem2数组里面全部是空字符
													//为什么要这样初始化?往下看(其实也是个人习惯) 
	
	if(*a=='-' && *(a+1)=='\n' && isalpha(*(a+2)))	//这里就是看是不是后面有连字符、换行符和字母连着
													//如果是那么前后合成一个单词 
	{
		while(!isalpha(*a))							//接下来的过程和上面几乎一样 
			a++;									//不过就是第一个循环
													//因为已经检测到后面有单词,不可能字符串戛然而止 
													//所以不需要再加判断返回了 
		b=a;
		while(isalpha(*b))
			b++;
		for(q=0;a!=b;a++,q++)
			tem2[q]=*a;
		tem2[q]='\0';								//经典字符串空字符结尾,别忘了
													//当然其实这步没有也无所谓,因为我已经memset了 
	}
	
	//第三部分 
	char *ttem=strcat(tem,tem2);					//这里我直接把两个数组合成在一起
													//其实不返回新数组也可以,直接用tem就行了
													//也是个人习惯吧 
													//注意!假如后面不需要合成单词的话 
													//那么这里就合成了个寂寞。但是是合法的!
													//【但是!如果我没有初始化,那么这一步就不合理了!】
													//【因为strcat函数是】 
													//【把后面的字符串替换前面字符串的第一个空字符】 
													//【那么这么做前面的字符串就没有空字符了,很危险!】 
	
	if(jud(ttem)==1)								//需要增加结构数组的元素 
	{
		for(w=0;w<sizeof(tem);w++)					//这一步看似是我失误了,把ttem打成tem 
			re[t].word[w]=ttem[w];					//实际上确实是我失误了,但是没有影响
													//因为strcat吧tem2传到tem的末尾,再把tem返回给ttem
													//实际上ttem和tem是相等的,所以没有完全失误 
		re[t].word[w]='\0'; 						//不要忘了结尾空字符 
		re[t].num=1;								//初始化为1 
		mem=t;										//【没用,忘删了】 
		t++;
	}
	if(*b=='\0') return i+(b-&chuan[i])-2;			//如果b是空字符的话,就返回空字符前一个位置的下标 
	return i+(b-&chuan[i])-1;						//如果不是就返回b的下标
													//现在看来其实没有必要
													//因为反正空字符也会超出条件范围退出循环的 
													//直接返回 i+(b-&chuan[i])-1 就行了
													//这也是我为什么说直接用下标不用指针可能会好写一点 
}
 
main()
{
    FILE *fp;
	if((fp=fopen("case1.in","r"))==NULL)//其实这里直接写
	{									//fp=fopen("case1.in","r"); 
		printf("NO"); 					//就可以了 
		return 0; 						//这么做纯粹个人习惯 
	}
	char ch,chuan[100000];				//这里创建了一个足够大的字符串用于接收文本 
	int n_max;							//代表了这个文本的长度( 有多少字符) 
	for(n_max = 0;(ch = fgetc(fp)) != EOF;n_max ++)
	{
		chuan[n_max] = tolower(ch);		//tolower(int) 这个来自于ctype.h的函数
										//如果接受到大写字母,就返回对应的小写字母
										//如果不是,就返回原来的字符 
	}	//等价于
		//if(chuan[n_max]>='A' && chuan[n_max]<='Z') chuan[n_max]-=32; 							 
	chuan[n_max]=0;						//字符串以空字符结尾,也可以写'\0' 
	
	int i=0,j=0,time=0;					//【 time 没用但是忘删了】 
	char *st=chuan,*en=chuan;			//【没用但是忘删了】 
	
	for(i=0;i<n_max;i++)				//字符处理函数 
		i=ret(chuan,i);					//把字符串中的单词整理到结构数组中 
	
	for(i=0;i<5;i++)					//一个简单的选择排序 
	{									//因为只输出5个所以 只排序5次 
		int k=i;
		for(j=i+1;j<t;j++)
			if((re[k].num<re[j].num)||(re[k].num==re[j].num&&strcmp(re[k].word,re[j].word)>0))
				k=j;
		struct wo a =re[k];				//直接交换结构体
		re[k]=re[i];
		re[i]=a;
	}
	for(i=0;i<5;i++)
		printf("%s %d\n",re[i].word,re[i].num);
	fclose(fp);							//防止以免中间会出什么以外,关闭文件放在最后(前面也行的)
	//没写return 0; 
}

4.总结

总结一下以上内容,捋一下思路还是很不错的

之前我上课爆肝200行代码没肝出来,捋顺思路之后一晚上肝了不到100行就出来了,说明思路还是很重要的。

其实存放问字符串可以放在全局变量,这样就不用传来传去,而且元素的数量可以标大一点,要是现在的我就直接1e8上了(haha)。

还有就是我的数据结构设计还是很乱的,因为边写边想,就这样吧。

希望各位同学顺利完成代码和实验报告,好好学好专业课啊!

对了,不要照抄哦(xixi)

不理解的可以在评论区提问!

标签:字符,华南农业大学,re,int,++,单词,程序语言,char,chuan
From: https://blog.csdn.net/2301_81246674/article/details/140804656

相关文章

  • Python 字节串转Hex字符串(一个久远的问题点总结)
    时间:2024.07.30作者:Yuan  这是一个今天看来似乎有点久远的问题,但是值得被记录和澄清一下!  那是在2022年1月份参与的一个项目中遇到的问题,大概需求是利用SHT40-AD1B-R2芯片,读取环境温度。其实就是通过i2c与这个温度传感器建立通讯,然后读取温湿度信息,对于上位机的......
  • 在 html 上添加 json 数据(数据包含多种特殊字符),使用 JSON.stringify 读取 error
    letjsonObj=[{ "Name":"test" "Attach":"www!@#$%^&*(){}|:\"<>?,./;'[]\\"}]lethtml=jsonObj.map((i,v)=>{ letjsonStr=JSON.stringify(jsonObj) return`<trdata='${json......
  • 如何将 panda 日期时间转换为特定日期格式,然后从中提取子字符串
    我在熊猫中有这个日期时间列。我正在将其转换为特定的日期格式。我想将此日期转换为字符串并从中提取子字符串。我发现很难做到。有谁知道如何。我的日期时间列中的数据如下所示:2024-01-3013:45:002024-01-3014:45:002024-01-3015:45:00我已使用以下语句将其转换......
  • DatetimeFormatter字符串转日期
    在Java中,我们经常需要将字符串形式的日期时间转换为LocalDateTime、LocalDate、LocalTime等日期时间对象,或者将日期时间对象转换为字符串。为了完成这些操作,我们可以使用DateTimeFormatter类。1.导入必要的类首先,确保你已经导入了必要的类:importjava.time.LocalDateTime;......
  • 将字符串转换为json格式
    我有一个Excel电子表格,当我直接在python中读取它时,它失败了。所以我先在PowerQuery中读,然后在python中读,但是在PowerQuery中读时丢失了json双引号。我尝试了demjson3,但无法成功。我尝试用Python逐行阅读,这不是一个好主意。我希望能够在python中将其呈现为json。......
  • 避免字符串连接的嵌套循环的 Pythonic 方法
    我想找到所有5位数字的字符串,其中前三位数字在我的第一个列表中,第二个槽第四个数字在我的第二个列表中,第三到第五个数字在我的最后一个列表中:l0=["123","567","451"]l1=["234","239","881"]l2=["348","551","399"......
  • 使用 Python + Beautiful Soup 抓取任何包含 5 个数字的字符串
    我住在德国,那里的邮政编码在大多数情况下都是5位数字。53525。我真的很想使用beautifulSoup从网站中提取该信息。我是Python/BeautifulSoup的新手,我不知道如何将“查找连续的每5个数字+“空格””翻译成Python语言。importrequestsimporturllib.re......
  • 在文档字符串中使用类型别名
    是否有在文档字符串中使用类型别名或typing对象的最佳实践?这个问题可能会吸引基于意见的答案。但也可能是对于特定解决方案有广泛接受的约定或外部工具支持。相关问题示例:函数返回带有字符串键和值的字典。您将在“返回”部分下的文档字符串中放入什......
  • 字符串和格式化输入/输出(解析)
    1:#include<stdio.h>intmain(void){ charname[40]; charsurname[40]; printf("Pleseinputyourfirstname:"); scanf("%s",name); printf("Pleseinputyourlastname"); scanf("%s",surname); printf(&quo......
  • 结合光学字符识别模型的GUI工具
    前言:先附上源码,项目太大(包含跑模型的训练文件)github上面放不下所以只能存网盘里。链接:https://pan.baidu.com/s/1bzu8psAHkLQzibvj0jzXXw提取码:6xx61系统功能描述1.1对图片和截图进行OCR识别对图片和截图进行OCR(OpticalCharacterRecognition,光学字符识别)识别功......