题目
针对一段中文文本,根据所给词典文件实现分词操作,并将分词结果显示在屏幕以及保存在文本中。
解题思路
先将语段存入字符串,将词典存入字符串指针数组中,再从语段的起始位置开始遍历语段,在词典中进行搜索匹配的词语,记录词语在词典中的位置,最后按照位置输出词典中的词语。其中,因为是分词操作,不要保留标点符号,所以需要注意标点符号的跳过,而中文标点符号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运行后