根据所给词典对语段进行分词操作【注释详细】

题目

针对一段中文文本,根据所给词典文件实现分词操作,并将分词结果显示在屏幕以及保存在文本中。

解题思路

先将语段存入字符串,将词典存入字符串指针数组中,再从语段的起始位置开始遍历语段,在词典中进行搜索匹配的词语,记录词语在词典中的位置,最后按照位置输出词典中的词语。其中,因为是分词操作,不要保留标点符号,所以需要注意标点符号的跳过,而中文标点符号ascll码为两个负数。

完整代码

#include<stdio.h>
#include<stdlib.h>
int com(char* p1, char* c1);//查看字符串是否含有某个标点符号 p1字符串 c1某个符号的字符串
void creat(char* pas1, char* words[999], int size);//对应词语并输出 pas1原字符串 words所有词语 size词语个数
FILE* pf; //文件指针
int main()
{
	char* address_words; char* address_passage; //词语文件地址 语段文件地址
	char* words[999]; int count = 0;  char* pas;//words所有词语 count词语个数  pas存储语段的字符串
	pas = (char*)malloc(10000);//分配内存
	address_words = (char*)malloc(1000);
	address_passage = (char*)malloc(1000);
	printf("请输入语段文件的地址及文件名:");//读入地址
	scanf("%s", address_passage);
	printf("请输入词语文件的地址及文件名:");
	scanf("%s", address_words);
	if ((pf=fopen(address_words, "r")) == NULL)//打开词语文件
	{
		perror("fopen");
		return 1;
	}
	words[count] = (char*)malloc(1000);//为第一个词语分配空间
	while (fscanf(pf,"%s", words[count]) != EOF)//读入每一个词语
	{
		count++;//词语个数增加
		words[count] = (char*)malloc(1000);//为下一个词语分配空间
	}
	fclose(pf);//关闭文件
	if ((pf = fopen(address_passage, "r")) == NULL)//打开语段文件
	{
		perror("fopen");
		return 1;
	}
	fgets(pas, 1000, pf);//读入语段
	fclose(pf);//关闭文件
	if ((pf = fopen(address_passage, "a")) == NULL)//再次打开语段文件
	{
		perror("fopen");
		return 1;
	}
	fprintf(pf, "\n ");
	printf("原语段为:\n%s\n分词后的语段为:\n",pas);//输出原语段
	creat(pas, words,count);//输出分词操作后的语段
	fclose(pf);//关闭文件
	return 0;
}
void creat(char* pas1, char* words[999],int size)
//对应词语并输出 pas1原字符串 words所有词语 size词语个数
{
	char* pas = pas1; char* temp = pas; char* word;//pas现在的语段指针的位置 temp暂存语段指针位置 word现在的词语
	int i = 0;//当前词语在所有词语(词典)中的位置
	while (*pas != '\0')//当语段指针位置没到末尾
	{
		word = words[i];//读取当前位置的词语
		pas = temp;//读取语段指针位置
		if( com(temp,",") || com(temp, "。") || com(temp, ";") || com(temp, "(") || com(temp, ")") || com(temp, "、"))//检查现在的位置是否有标点符号
		{
			temp=temp+2;//跳过标点符号
			pas = temp;
		}
		if (*temp == ' ')//检查现在的位置是否有空格
		{
			temp++;
			pas = temp;
		}
		while (*word!= '\0')//当词语没到末尾
		{
			if (*word!= *pas) { break; }//如果当中的某个字符不一样则跳出
			word++;//逐个字符比较,词语指针后移
			pas++;//语段指针后移
		}
		if (*word== '\0') //如果当前词语匹配语段
		{ 
			printf("%s ", words[i]);//打印词语
			fprintf(pf, "%s ", words[i]);//输出到文件
			temp = pas; //语段指针位置移向下一个位置
		}
		i++;//下一个词语
		if (i == size)//如果词语位置到达词典末尾则从头再来
			i = 0;
	}

}
int com(char* p1, char* c1)
//查看字符串是否含有某个标点符号 p1字符串 c1某个符号的字符串
{
	char* c = c1;//某个符号的字符串
	char* p = p1;//字符串
	while (*c != '\0')//当没有到标点符号最后一个ascll码值
	{
		if (*p != *c)return 0;//如果不相等则返回0
		c++;
		p++;
	}
	return 1;//完全相等则说明有某个标点符号,返回1
}

运行截图

//passage运行前

//passage运行后

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值