KWIC实验报告(C++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
软件体系结构
上机实验报告书中国石油大学(北京)信息学院
计算机科学与技术系
制订人:周新
学号:
指导教师:朱雪峰博士
2011年10月27日
1、课程实验目的
通过KWIC(Key Word in Context)检索系统,对软件体系结构有更加深入的了解和认识。
通过运用几种体系结构,熟悉常见的软件体系结构,并对这几种结构有进一步了解。
2、任务概述
用管道过滤器,主程序、子程序,抽象数据类型,隐式调用这四种结构来分别实现KWIC检索系统。
3、实现方法
用C++主要实现了两种结构:主程序、子程序结构,抽象数据类型。
(1)KWIC1工程的入口函数
int _tmain(int argc, _TCHAR* argv[])
{
//界面,结构选择
cout<<"Input a absolute filename:";
char filename[30];
cin>>filename;
cout<<"Choose KWIC function"<<endl<<"1 is Main Program/Subroutine with Shared Data"<<endl<<"2 is Abstract Data Types"<<endl;
int choose=0;
cin>>choose;
if(1==choose)//主程序和子程序
{
MainSubroutine mainSub;
vector<vector<string> > lines=mainSub.readLines(filename);
vector<LINE> lineIndex=mainSub.shiftString(lines);
lineIndex=mainSub.firstAlphaSort(lineIndex,lines);
mainSub.outPut(lineIndex,lines);
}
else//抽象收据类型
{
Lines *lines=new Lines;
Input input;
Shift *shift=new Shift;
FirstAlphaSort alphaSort;
Output output;
input.readLines(filename,*lines);
shift->circularShift(*lines);
alphaSort.alphaSort(*shift);
output.print(alphaSort);
delete shift;
delete lines;
}
return 0;
}
(2)主程序、子程序结构实现类
//从文件中按行读取
vector<vector<string> > MainSubroutine::readLines(char* filename)
{
vector<vector<string> > dst;
ifstream infile(filename,ios::in);
if(!infile)
{
cout<<"open error!"<<endl;
exit(0);
}
char temp[100]="";//存储从文件中读取的行的临时变量
//按行读取
while(infile.getline(temp,100))
{
int k=0,j=0;
vector<string> line;
line.swap(vector<string>());
char s[20]="";//存储从行中取字符串的临时变量
while(temp[k]!=0)
{
//每个单词的截取条件为下一个字符为空格或者为行的末尾
if((temp[k+1]==' '||temp[k+1]==0)&&temp[k]!=' ')
{
s[j]=temp[k];
s[j+1]='\0';
string ss=s;
line.push_back(ss);
j=0;
}
else if(temp[k]==' ')
{
j=0;
}
else
{
s[j]=temp[k];
j++;
}
k++;
}
dst.push_back(line);//将从文件中中读出的行加入到dst中}
infile.close();
for(int i=0;i<dst.size();i++)
{
for(int j=0;j<dst.at(i).size();j++)
{
cout<<dst[i][j]<<" ";
}
cout<<endl;
}
cout<<endl<<endl;
return dst;
}
//循环左移
vector<LINE> MainSubroutine::shiftString(vector<vector<string> > srcLines)
{
vector<LINE> shiftLines;
for(int row=0;row<srcLines.size();row++)
{
int colnum=srcLines[row].size();//获取每一行的字符串个数
//对第row行循环colnum(字符串个数)次,生成循环移位后的colnum 行
for(int col=0;col<colnum;col++)
{
LINE linePos;//声明存放一行的行标以及各列的列表的结构体
linePos.rowIndex=row;//给行标赋值
//循环生成一行的列标
for(int colshift=0;colshift<colnum;colshift++)
{
}
shiftLines.push_back(linePos);
}
}
return shiftLines;
}
//字母排序
vector<LINE> MainSubroutine::firstAlphaSort(vector<LINE> lineIndex,vector<vector<string> > srcLines)
{
vector<vector<char> > firstChar;
vector<LINE> dstIndex;
for(int row=0;row<srcLines.size();row++)
{
vector<char> firstCharLine;
//逐行提取各个字符串的首字母
for(int col=0;col<srcLines[row].size();col++)
{
firstCharLine.push_back(srcLines[row][col][0]);
}
firstChar.push_back(firstCharLine);//
}
int rowPos=0;
int colPos=0;
//外面的两层for循环是控制循环次数的
//内部的两层for循环是遍历所有的字符串首字母,寻找最小的字母
for(int row=0;row<firstChar.size();row++)
{
for(int col=0;col<firstChar[row].size();col++)
{
char min='z';
for(int row=0;row<firstChar.size();row++)
{
for(int col=0;col<firstChar[row].size();col++)
{
if(min>=firstChar[row][col]&&'
'!=firstChar[row][col])
{
rowPos=row;
colPos=col;
min=firstChar[row][col];
}
}
}
firstChar[rowPos][colPos]=' ';
int linePos=0;//在原行矩阵中的位置
for(int line=0;line<rowPos;line++)
{
linePos+=srcLines[line].size();
}
linePos=linePos+colPos;
dstIndex.push_back(lineIndex[linePos]);
}
}
return dstIndex;
}
//按照lineIndex中的字符串的行标和列标输出所有字符串
void MainSubroutine::outPut(vector<LINE> lineIndex, vector<vector<string> > srcLines)
{
for(int row=0;row<lineIndex.size();row++)
{
for(int col=0;col<lineIndex[row].colIndex.size();col++)
{
cout<<srcLines[lineIndex[row].rowIndex][lineIndex[row].colIndex[col]]<<
" ";
}
cout<<endl;
}
cout<<endl;
}
(3)抽象数据类型结构实现
行存储类
//增加行
//参数:line字符串向量列表
void Lines::addLine(vector<string> line)
{
lines.push_back(line);
}
//从存储结构中获取某一行
//参数:lineIndex为获取的行的序号,从0开始
//返回获取的行
vector<string> Lines::getLine(int lineIndex)
{
return lines[lineIndex];
}
// 增加字符串
//参数:instring为所添加字符串,lineIndex为字符串所在行的序号(从0开始)void Lines::addString(string instring, int lineIndex)
{
lines[lineIndex].push_back(instring);
}
//获取字符串
//参数:lineIndex为行序号,stringIndex为字符串在行中的序号
//返回获取的字符串
string Lines::getString(int lineIndex,int stringIndex)
{
return lines[lineIndex][stringIndex];
}
//增加字符
//参数:inchar为增加的字符,stringIndex为增加的字符所在的字符串的序号,lineIndex为增加的字符所在的行的序号
void Lines::addChar(char inchar, int stringIndex, int lineIndex)
{
lines[lineIndex][stringIndex].push_back(inchar);
}
//获取字符
//参数:lineIndex为行序号,stringIndex为字符串的序号,charIndex为字符的序号
//返回获取的字符
char Lines::getChar(int lineIndex, int stringIndex, int charIndex)
{
return lines[lineIndex][stringIndex][charIndex];
}
//获取总的行数
int Lines::getLineNum(void)
{
return lines.size();
}
//获取特定行的字符串个数
int Lines::getStringNum(int lineIndex)
{
return lines[lineIndex].size();
}
输入类
void Input::readLines(char* filename, Lines &readLines)
{
// vector<vector<string> > dst;
ifstream infile(filename,ios::in);
if(!infile)
{
cout<<"open error!"<<endl;
exit(0);
}
char temp[100]="";//存储从文件中读取的行的临时变量
int lineIndex=0;//行序号
//按行读取
while(infile.getline(temp,100))
{
int k=0,j=0;
vector<string> line;
line.swap(vector<string>());
readLines.addLine(line);
char s[20]="";//存储从行中取字符串的临时变量
int stringIndex=0;//字符串序号
readLines.addString(s,lineIndex);
while(temp[k]!=0)
{
if(temp[k]!=' ')
{
readLines.addChar(temp[k],stringIndex,lineIndex);
}
//每个单词的截取条件为下一个字符为空格或者为行的末尾
if(temp[k]==' '&&temp[k+1]!=' ')
{
// readLines.addChar(temp[k],stringIndex,lineIndex);//将该字符串加入到指定行的指定字符串中
// readLines.addChar('\0',stringIndex,lineIndex);
s[0]='\0';//清空字符串
readLines.addString(s,lineIndex);
stringIndex++;//字符串序号加1
}
k++;
}
lineIndex++;
// dst.push_back(line);//将从文件中中读出的行加入到dst中
}
infile.close();
for(int i=0;i<readLines.getLineNum();i++)
{
for(int j=0;j<readLines.getStringNum(i);j++)
{
cout<<readLines.getString(i,j)<<" ";
}
cout<<endl;
}
cout<<endl<<endl;
}
循环左移类
//实现所有行的循环移位
void Shift::circularShift(Lines srcLines)
{
int lineIndex=0;
for(int row=0;row<srcLines.getLineNum();row++)
{
int cols=srcLines.getStringNum(row);
for(int col=0;col<cols;col++)
{
vector<string> newLine;
lineShift.addLine(newLine);
for(int newcol=0;newcol<cols;newcol++)
{
lineShift.addString(srcLines.getString(row,(col+newcol)%cols),lineIndex);
}
lineIndex++;
}
}
}
//获取所有行
Lines Shift::getLines(void)
{
return lineShift;
}
//获取某一行
vector<string> Shift::getLine(int lineIndex)
{
return lineShift.getLine(lineIndex);
}
//获取某一行中某一位置的字符串
string Shift::getString(int lineIndex,int stringIndex)
{
return lineShift.getString(lineIndex,stringIndex);
}
//获取某一行中某一个字符串中的某一位置的字符
char Shift::getChar(int lineIndex, int stringIndex, int charIndex) {
return lineShift.getChar(lineIndex,stringIndex,charIndex); }
//获取行数
int Shift::getLineNum(void)
{
return lineShift.getLineNum();
}
//获取某一行的字符串个数
int Shift::getStringNum(int lineIndex)
{
return lineShift.getStringNum(lineIndex);
}
排序类
//实现按首字母排序
void FirstAlphaSort::alphaSort(Shift srcShiftLines)
{
shiftLines=srcShiftLines;//将传进得Shift对象赋值给成员变量
vector<char> firstChar;
for(int row=0;row<shiftLines.getLineNum();row++)
{
firstChar.push_back(shiftLines.getChar(row,0,0));//获取首字母}
//首字母排序
for(int loop=0;loop<firstChar.size();loop++)
{
char min='z';
int rowIndex=0;
for(int row=0;row<firstChar.size();row++)
{
if(min>=firstChar[row]&&' '!=firstChar[row])
{
min=firstChar[row];
rowIndex=row;
}
}
charSort.push_back(rowIndex);
firstChar[rowIndex]=' ';//将找到的最小的字母置为‘’,以便在下一次查找时不再保留
}
}
//首字母排序
vector<int> FirstAlphaSort::getCharSort()
{
return charSort;
}
//获取行数
int FirstAlphaSort::getLineNum(void)
{
return shiftLines.getLineNum();
}
//按行的序号,将各字符串合并成一个字符串,然后获取一行
//lineIndex为行序号
string FirstAlphaSort::getLineAsString(int lineIndex)
{
string lineString;
for(int strCount=0;strCount<shiftLines.getStringNum(lineIndex);strCount++)
{
lineString+=shiftLines.getString(lineIndex,strCount)+" ";
}
lineString+="\0";
return lineString;
}
输出类
//按字母表顺序输出
void Output::print(FirstAlphaSort sortLines)
{
for(int row=0;row<sortLines.getLineNum();row++)
{
cout<<sortLines.getLineAsString(sortLines.getCharSort()[row])<<endl;
}
cout<<endl;
}
4、实验的例程
(1)主程序、子程序运行结果
1选择的
实现结构
为主程
序、子程
序
(2)抽象收据类型
2选择的
实现结构
为抽象数
据类型
5、总结
通过本次实验,首先对软件体系结构有了更真切的了解,尤其是对管道过滤器结构,主程序、子程序结构,抽象数据类型结构,隐式调用这四种结构的理解更加透彻了。
同时还对KWIC有个一个认知的过程。
在实现的上述两种结构的过程中,对增强了数据结构的掌握,以及对面向对象概念的进一步理解。
编程时,遇到了各种大大小小的问题,尤其是数据结构定义方面的,深刻体会到了数据结构的重要性,同时发现了自己编写的代码移植性以及编码风格都不是很好,希望老师给予指点。