实验一Word文档下载推荐.docx
- 文档编号:19015470
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:48
- 大小:68.65KB
实验一Word文档下载推荐.docx
《实验一Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《实验一Word文档下载推荐.docx(48页珍藏版)》请在冰豆网上搜索。
(分隔符,;
)
第二部分:
停用词过滤,分为“产生随机停用词”、“产生随机待过滤文本”和“过滤停用词”3个小实验。
产生随机停用词:
生成一个文件长度和单词平均长度可控的文本文件,要求字符集为26个字母,每行生产一个单词,每个单词的长度随机,全部单词的平均长度可控制,通常为4、5(非严格要求),总共输出的文件长度可控制。
产生随机待过滤文本:
生成一个文件大小和单词平均长度可控的文本文件,要求
字符集为26个字母+“”(空格)+“\r\n”(回车换行);
从文件开始一直到结束,持续输出,不额外换行(除非遇到生成的\r\n),总共输出的文件大小可控制。
过滤停用词:
写一个程序,快速扫描待过滤文本,然后将待过滤文本中出现的所有停用词,替换为“**”,要求禁用正则表达式,不要误杀(例如,若停用词包括“abc”,那么“abcd”等不应该被误杀。
第三部分:
文法化简
设计文法类,实现对文法G[S]=(Vt,Vn,P,S)的文件读写,文法的文件表示形式以及内存表示形式可自定义。
本质上,文法就是3个集合+1个符号,重点(难点)是产生式集合如何处理。
文法的文本形式可根据自己需要自由定义。
在前述的基础上,实现文法化简的无用符号及无用产生式消除算法(即课本算法2.1、2.2)。
方法、步骤:
要完成本实验,依据实验要求进行分解,需要完成的实验步骤是:
1.如何读写文件?
读写文法文件内容,需要用到文件IO,查阅、复习文件IO操作。
答:
本次实验使用C++来编写,完成读取文件的操作为freopen()函数和ifstream类。
freopen()函数包含在头文件stdio.h中,可用于重定向输入输出流,形式为freopen(constchar*filename,‘r’,stdin),一般在C++中配合cin操作,比如while(cin>
>
str){·
·
},其中str是已定义的string字符串,表示将文件一个个读取赋值给str,不包括空格和换行;
而ifstream类的操作表示将文件全部内容一次性读取赋值,包括空格和换行,头文件为fstream.h。
写入文件的操作是freopen()函数,形式为freopen(constchar*filename,‘w’,stdout),在C++中一般配合cout操作。
2.如何分词?
第一部分实验要求进行分词,源代码中的单词可以分成3类,一类是约定的保留字,一类是普通标识符,最后一类是数字
2.1如何识别保留字?
2.2如何识别标识符?
2.3如何识别数字?
特别的,如果你有多种方法来识别这3类单词,那这些方法有何优缺点?
分析并作出你的选择。
该实验由于是学生自定义文法,所以开放性较大。
本人定义的表达式中的保留字、标识符和数字之间必须以空格或者换行隔开,否则将视为一个整体进行识别,因此在识别单词过程过只要利用string类型比较相等符号“==”即可识别保留字,标识符本人的定义是仅限包含于26个大小写字母,因此只要利于for循环查询单词中单个字符是否是26个字母之中即可,进行之前得先进行保留字识别;
识别数字跟标识符同理,只要判断在单词中全部字符是否均为0~9个数字之内即可。
3.如何产生符合要求的随机停用词和待处理文本
第二部分实验要求先产生随机的停用词和待处理文本,主要是如何产生符合要求的这些词或文本?
3.1如何产生随机停用词?
3.2如何控制随机停用词的平均长度(而不是固定长度)?
3.3如何产生待处理文本中的“段落”?
3.4如何控制待处理文本的长度?
3.1在确定随机停用词长度的前提下,定义int类型变量temp,其中temp在0~25之间随机赋值,则单词字符可为50%概率的’A’+temp或50%概率的’a’+temp。
3.2先随机产生1~固定长度*2的随机数,下一步这些随机数将有50%的概率变成固定长度,50%的概率保持不变。
3.3换行需要4个字符,与26个字符比差不多1:
6,则定义一个1~6的随机变量,当变量等于1时就换行,否则输出单词。
3.4待处理文本总长度为输入数据,本人定义字符、空格占1个字符,换行占4个字符,当最后一个单词少于随机停用词的平均长度时,采用“突然截断”,即输出即可。
4.如何过滤停用词
第二部分实验最后要求把待处理文本中出现的停用词替换为“**”,那你如何准确、快速判断出文本中的停用词?
该实验理解起来就是字符串之间的查找替换操作。
思路为:
先用ifstream类操作将“待处理文章”的全部内容读取到字符串bstr中,再调用输入输出流的函数freopen()将“停用词”表的字符串以空格、换行为分离标准读取一个个单词sstr,此时就是两个字符串bstr与sstr的查找替换操作,利用KMP算法就能快速地实现此操作,KMP时间复杂度为O(n),所以运行效率很快。
5.如何设计文法类?
文法类里面,有3个集合,1个特别的非终结符——开始符号。
集合应如何表示?
Set<
aType>
是常见的范型,可使用例如Set<
Production>
来表示产生式的集合。
也可直接采用数组等形式来表示,那种方法更好?
分析并做出你的设计。
对于非终结符和终结符,本人采用的是直接采用char类型数组表示,对于产生式集采用的是自定义类来表示。
相对于数组由于拥有已定义函数,操作比较便利,效率高,且Set<
定义的集合具有互异性,所以不必考虑是否插入相同元素,而数组必须检查原数组中是否含有相同元素再执行插入操作。
但Set<
相比与数组更耗内存,且数组下标操作也更灵活。
因此本人倾向于采用数组。
6.如何实现无用文法的化简算法?
算法2.1、2.2课本已经给出了说明,那你如何将算法说明变成代码?
有什么主要内容?
算法2.1、2.2均使用for循环实现。
对于算法2.1,重新定义char数组表示非终结符集,并重新定义类数组表示产生式集。
算法第2,3步主要通过for循环来检测产生式中右侧的终结符和非终结符,第5步需要先检测产生式左侧字符,如果左侧字符存在于非终结符集中,再检测右侧符号,而不是两边一起检测。
对于算法2.2,重新定义char数组分别表示非终结符集和终结符集,并重新定义类数组表示产生式集。
该算法的主要操作在第3步,需要先检测产生式左侧字符,如果左侧字符存在于非终结符集中,则存放在非终结符集中,再检测右侧符号,直到for循环完毕。
第5步只需要将产生式集的左右符号检测是否在非终结符集和终结符集中即可。
实验过程及内容:
实验过程及内容,处理代码设计说明、代码及其注释外,特别关注编程过程。
要求,至少有一张照片,照片上出现你(正面)+正在写的代码(电脑要有外观)
照片:
实验1.1
文法自定义说明:
标识符:
由26个英文字母组成,包括大小写;
整数:
相当于C++中整数类型;
小数:
相当于C++中浮点数类型;
:
=:
赋值符号;
+:
加法;
-:
减法;
*:
乘法;
/:
除法;
++:
双目加法;
--:
双目减法;
:
大于号;
<
小于号;
大于等于号;
小于等于号;
==:
相等号;
!
不等号;
;
分隔符;
(:
左括号;
):
右括号;
for循环语句:
=<
for>
<
左括号>
标识符>
赋值符号>
整数>
|<
小数>
分隔符>
大于号>
|<
小于号>
大于等于号>
小于等于号>
加法>
减法>
乘法>
除法>
右括号>
;
赋值语句:
浮点数>
;
语句表:
for循环语句>
赋值语句>
·
。
注:
所有符号之间须以空格隔开,未出现的定义均视为非法字符。
实现代码:
#include<
iostream>
cstring>
string>
#defineF17
usingnamespacestd;
stringForArray[F];
//存放for
intForSF[F]={1,2,3,4,5,6,3,7,5,6,3,4,3,8,5,9,6};
//for标准
stringAssignArray[100];
//存放赋值语句
boolissen=false;
stringSenArray[100][100];
//存放语句表
boolIdentCode(stringstr)//标识符
{
inti=0;
while(((str[i]<
='
z'
&
&
str[i]>
a'
)||(str[i]<
Z'
A'
))&
i<
str.length())
i++;
if(i==str.length())
returntrue;
returnfalse;
}
boolAssignCode(stringstr)//赋值
if(str.length()!
=2)
returnfalse;
if(str[0]=='
'
str[1]=='
='
)
boolIntCode(stringstr)//整数
9'
0'
if(i==str.length())
boolFloatCode(stringstr)//小数(只允许出现一个小数点)
boolform=false;
if(i>
0)
form=true;
if(str[i]=='
.'
form)
boolAddCode(stringstr)//加法
=1)
+'
)
boolSubCode(stringstr)//减法
-'
)
boolMultCode(stringstr)//乘法
*'
boolDiviCode(stringstr)//除法
/'
boolAddAddCode(stringstr)//++号
boolSubSubCode(stringstr)//--号
boolBigCode(stringstr)//大于号
boolBigSCode(stringstr)//大于等于号
boolSmallCode(stringstr)//小于号
boolSmallSCode(stringstr)//小于等于号
boolEqualCode(stringstr)//相等号
boolUnequalCode(stringstr)//不等号
boolSepCode(stringstr)//分隔符
boolLeftCode(stringstr)//左括号符
('
boolRightCode(stringstr)//右括号符
)'
intf=0;
//sf
intff=0;
//ForArray
boolisf=false;
//是否有for出现
intsf[F];
//检测位置是否符合标准
voidForInit()
f=0;
ff=0;
isf=false;
for(intj=0;
j<
F;
j++)
sf[j]=0;
boolForCode(stringstr)//for语句
if(f>
=F)
isf=false;
if(str=="
for"
{
//初始化
ForInit();
ForArray[ff++]=str;
sf[f++]=1;
isf=true;
}
elseif(LeftCode(str)&
isf)
sf[f++]=2;
elseif(IdentCode(str)&
sf[f++]=3;
elseif(AssignCode(str)&
isf)
sf[f++]=4;
elseif((IntCode(str)||FloatCode(str))&
sf[f++]=5;
elseif(SepCode(str)&
sf[f++]=6;
elseif((BigCode(str)||BigSCode(str)||SmallCode(str)||SmallSCode(str))&
sf[f++]=7;
elseif((AddCode(str)||SubCode(str)||MultCode(str)||DiviCode(str))&
sf[f++]=8;
elseif(RightCode(str)&
//for(i:
=0;
9;
i:
=i+1);
sf[f++]=9;
for(inti=0;
i<
i++)
if(sf[i]!
=ForSF[i])
returnfalse;
ForInit();
returntrue;
inta=0;
intaa=0;
boolisa=false;
intsa[100];
voidAssignInit()
a=0;
aa=0;
isa=false;
boolAssignSCode(stringstr)//赋值语句
if(a>
100)
isa=false;
if(IdentCode(str)&
!
isa)
sa[a]=1;
AssignArray[aa]=str;
elseif((IdentCode(str)||IntCode(str)||FloatCode(str))&
isa)
sa[++a]=1;
AssignArray[++aa]=str;
elseif(AssignCode(str))
AssignInit();
isa=true;
sa[++a]=2;
sa[++a]=3;
sa[++a]=4;
else
sa[++a]=5;
=a;
if(i%2==0)
if(sa[i]!
returnfalse;
if(i==1)
if(i%2==1&
i!
=a&
=3)
if(i==a)
=4)
intmain()
freopen("
in.txt"
"
r"
stdin);
out.txt"
w"
stdout);
stringstr;
inti,j;
ints=0;
while(cin>
str)
if(ForCode(str))
{
cout<
"
("
for(i=0;
cout<
ForArray[i]<
"
for循环语句)"
endl;
s++;
//cout<
s<
for(j=0;
{
Se
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)