用VC实现复杂记事本.docx
- 文档编号:18227855
- 上传时间:2023-04-24
- 格式:DOCX
- 页数:50
- 大小:469.73KB
用VC实现复杂记事本.docx
《用VC实现复杂记事本.docx》由会员分享,可在线阅读,更多相关《用VC实现复杂记事本.docx(50页珍藏版)》请在冰豆网上搜索。
用VC实现复杂记事本
数据结构与算法综合训练
目录
实验一:
WordSearchPuzzle
一、WordSearchPuzzle的实验综述
1.1问题介绍
1.2设计目标
二、WordSearchPuzzle的系统分析
2.1数据类型信息和数据结构
2.2数据结构分析
三、WordSearchPuzzle的系统设计
3.1系统设计的任务及原则
3.2系统总体结构分析
四、WordSearchPuzzle的系统实施
4.1系统开发环境
4.2模块功能实现
4.3系统运行结果与调试
五、系统评价
5.1优缺点分析
实验二:
复杂记事本NotePad
一、NotePad的实验综述
1.1开发背景
1.2问题介绍
1.3设计目标
二、NotePad的系统分析
2.1数据类型信息和数据结构
2.2数据结构分析
三、NotePad的系统设计
3.1系统设计的任务及原则
3.2系统总体结构分析
四、NotePad的系统实施
4.1系统开发环境
4.2模块功能实现
4.3系统运行结果与调试
五、系统评价
5.1优缺点分析
实验总结
参考文献
图0系统开发流程图
实验一:
WordSearchPuzzle
一WordSearchPuzzle的实验综述
1.1问题介绍
问题描述:
WordSearchPuzzle(以下简称WSP)是一个由字母组成的二维数组和单词列表构成的单词游戏。
该游戏的目标就是要在这个字符数组中寻找单词列表中的单词。
这些单词在二维数组中可以以水平、垂直和斜线这三种形式出现(注意:
对于斜线方式,则本身就含有两种不同角度的斜线形式,即从左上向右下和从右上向左下),同时对于任何一种形式都可以有两种方向(例如,水平形式则可以从左向右的方向,也可以是从右向左的方向)。
图1则是一个具体的WSP的示意图:
badminton
baseball
bocce
bowling
boxing
fencing
football
golf
hockey
polo
rugby
skiing
soccer
tennis
图1
现在我们要改变WSP的构成部分,也就是只出现字母组成的二维数组,而不提供候选的单词列表。
这样做的目的是让我们能够在给定的字母数组中去探索或者发现里面都有什么单词。
也就是说原有的WSP的单词候选列表中的单词个数是少量的,而现在我们则将单词候选列表扩展为整个英语词典。
可以想象,这将带来大量的搜索操作。
怎么解决?
这需要我们从数据结构的选择和算法的设计上下功夫。
1.2新系统目标
WordSearchPuzzle的设计目标是,对原有的WSP游戏进行改进。
原有的WSP游戏单词范围有限且每次必须给出单词的范围。
新系统只给出字母组成的二维数组,而不提供单词列表。
这样让单词的候选范围扩充至整个英文单词表。
极大地扩充了WSP游戏的内容。
同时设计数据结构保证系统的时间和空间效率。
WSP程序的要求有以下几点:
1、程序需要实现单词范围的扩充。
2、程序的算法效率必须得到保障。
3、程序应具有易操作,具有简洁实用的图形界面。
并实现矩阵的可扩充性。
二WSP的系统分析
2.1数据结构
当我们将单词候选列表扩展为整个英语词典。
将带来大量的搜索操作。
于是需要我们从数据结构的选择和算法的设计上下功夫。
在这里我们选用Trie树来存储英文词典。
2.1.1Trie树的基本定义
Trie,又称单词查找树,是一种树形结构,是一种哈希树的变种。
典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。
它的优点是:
最大限度地减少无谓的字符串比较,查询效率比哈希表高。
性质
它有3个基本性质:
1.根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2.从根节点到某一字符,路径上经过的字符连接起来,为该节点对应的字符串。
3.每个节点的所有字节点包含的字符都不相同。
图示
这是一个Trie结构的例子:
在这个Trie结构中,保存了A、to、tea、ted、ten、i、in、inn这8个字符串,仅占用8个字节(不包括指针占用的空间)。
2.1.2本例中Trie树的实现和ADT
本例中的Trie并非使用传统的数组形式存储,而采用二叉树的形式存储,表示方法采用孩子兄弟表示法,这样做尽管牺牲了一部分的效率,但对于程序的后续实现是十分方便的,可以使用前序遍历等一系列二叉树的算法思想。
树和森林的孩子兄弟表示法,又称二叉树表示法,或二叉链表表示法。
树中每个结点都设有两个指针,其一,firstchild指向该结点的“第一个”子树根结点;其二,nextsibling指向它的"下一个"兄弟结点。
这里的"第一个"和"下一个"都没有逻辑上的含义,只是在构造存储结构时自然形成的次序。
对森林来说,可认为各棵树的根结点之间是一个“兄弟”关系。
由于二叉树和树都可用二叉链表作为存储结构,
图3Trie树的左子节点右兄弟表示法
如图所示的二叉Trie树中存储了able,ache(vi.疼痛)等一系列单词,其中$作为单词的结束标志。
ADT:
classTrie
{
public:
Node*root,*current;
public:
Trie();
~Trie();
voidInsert(Node*subTree,char*word);
voidcreate_bin();
voidDelete(Node*subTree);
intTrie:
:
Search(char*word);
};
2.2数据类型信息
(1)Trie树中每个节点以结构体存储:
structNode{
chardata;
Node*firstChild,*nextSibling;
Node(charvalue='\0',Node*fc=NULL,Node*ns=NULL):
data(value),firstChild(fc),nextSibling(ns){}
};
(2)读入的矩阵以二维数组的形式储存。
三WordSearchPuzzle系统设计
3.1系统设计的任务及原则
3.1.1任务
对原有的WSP游戏进行改进。
原有的WSP游戏单词范围有限且每次必须给出单词的范围。
3.1.2原则
系统性:
程序是作为统一整体存在的,因此,系统设计中界面风格要一致,操作方法一致,系统的代码要统一。
可靠性:
程序应该经过多次测试,保证每一个位置,每一个方向的单词都能被查找出来。
高效性:
保证时间复杂性尽可能小。
3.2系统总体结构设计
3.2.1系统功能描述
WSP程序由一个单个对话框构成。
其基本结构:
(1)导入按钮:
从文本中导入矩阵。
(2)矩阵长宽:
获取矩阵的长度和宽度。
(3)显示控件:
为ListBox控件,显示出单词搜索的结果,包括行数,列数,单词,方向等信息。
(4)开始按钮:
开始搜索。
四WordSearchPuzzle的系统实施
4.1系统开发环境
MicrosoftVisualStudio2008SP2
WithMFC
4.2功能实现
4.2.1窗体及代码设计
1.创建工程WordPuzzle
2.创建主窗体
新建窗体,如下图:
图4.2.2主程序窗体
用户操作说明:
当用户点击开始按钮时,从程序开始从文件中读入矩阵,并返回矩阵的长和宽。
然后用户继续点击开始按钮,在下方的ListBox控件中显示出层序运行的结果。
3.导入按钮代码:
用户操作说明:
点击导入后,将文件中的矩阵打印到左上方的ListBox中。
代码:
voidCwordgameDlg:
:
OnBnClickedLoad()//从文件导入
{
stringifile("example1.txt");//确定要导入的文件
stringtemp;
ifstreaminfile;
CStringdata;
CStringmatrix;//以一维数组矩阵
infile.open(ifile.c_str(),ifstream:
:
in);//打开文件
getline(infile,temp);
data.Format("%s",temp.c_str());
m_l.SetWindowTextA(data);//获取矩阵行数,m_l为矩阵行数
center_matrix.length=atoi(data.GetBuffer(data.GetLength()));//length为矩阵的总行数
getline(infile,temp);
data.Format("%s",temp.c_str());
m_w.SetWindowTextA(data);//获取矩阵行数,m_l为矩阵行数
center_matrix.width=atoi(data.GetBuffer(data.GetLength()));//width为矩阵的总行数
while(getline(infile,temp))//逐行读入,使文本内容全部储存到Matrix中
{
data.Format("%s",temp.c_str());
matrix+=data;
matrix+="\r\n";//加上换行符
}
m_matrix.SetWindowText(matrix);
inti=0;
intj=0;
intt=0;
for(i=0;i { for(j=0;j { center_matrix.mat[i][j]=matrix[t]+32; t++; } t+=2; } infile.close();//关闭文件 UpdateData(false);//更新控件显示 } 算法分析: 本函数主要实现从文件读取矩阵的操作,首先读取出行列信息,然后用while循环逐行读取到一个字符串中,再将字符串按格式转化为二维数组。 从而实现二维数组的读取。 4.开始按钮 用户操作说明: 用户在执行导入矩阵操作后,在后台已经将此矩阵存储起来。 此时点击开始,在后台会调用一系列的函数,完成搜索的功能。 调用的顺序: 先调用Trie: Create()建立Trie树,在此函数中循环读入每行单词,并每次调用Trie: : Insert(),Trie树建立后,在调用Search_word函数,此函数将对二维数组每一个位置进行8方向的搜索,调用Seach_1st,Search_2nd,…,遍历完二维数组的每一个位置后,即显示出搜索的全部结果。 为了方便说明,列出点击开始按钮以后函数的调用情况: …… 下面对设计到的每一个函数进行详细说明: Trie树建立函数: voidTrie: : create() { stringifile("Vocabulary.txt"); stringtemp; char*s=NULL; intl; ifstreaminfile; infile.open(ifile.c_str(),ifstream: : in);//打开Vocabulary.txt准备读写 while(getline(infile,temp))//逐行读取,建立Trie树 { l=temp.size(); s=newchar[l+2]; temp.copy(s,l); s[l]='$'; s[l+1]='\0'; Insert(root,s);//插入本单词 deletes; s=NULL; } infile.close(); }; 算法分析: 循环将Vocabulary.txt中逐行读取,每次调用Insert()函数插入Trie。 向Trie中插入单个单词: voidTrie: : Insert(Node*subTree,char*word)//向Trie树中添加单个单词 { current=subTree; if(current->firstChild==NULL)//当当前位置的左孩子等于空时,增加左孩子结点并赋值为word下一个单词 { while(*word! ='\0') { current->firstChild=newNode; current->firstChild->data=*(word++); current=current->firstChild; } } else//当当前位置左孩子不等于空 { current=current->firstChild;//向下一层 while(current->data! =*word&¤t->nextSibling! =NULL)//在该层查找word字串中当前字母,直到超界 { current=current->nextSibling; } if(current->data==*word)//如果当前Trie树的字母等于word对应字母,进行下一次递归。 { Insert(current,word+1); } else { current->nextSibling=newNode(); current->nextSibling->data=*(word); current=current->nextSibling; Insert(current,word+1); } } }; 算法分析: 本函数通过递归的方式,遍历每一层每一个节点进行判断,并将新的元素进行插入。 主搜索函数: voidsearch_word(CListBox&lb,char**a,intlength,intwidth) { for(inti=0;i<=width;i++)//对矩阵每个行的遍历 { for(intj=0;j<=length;j++)//对矩阵每个列的遍历 { search_1st(lb,a,i,j,length,width);//向下进行搜索 search_2nd(lb,a,i,j,length,width);//向右进行搜索 search_3rd(lb,a,i,j,length,width);//向右下进行搜索 search_4th(lb,a,i,j,length,width);//向左下进行搜索 search_5th(lb,a,i,j,length,width);//向上进行搜索 search_6th(lb,a,i,j,length,width);//向左进行搜索 search_7th(lb,a,i,j,length,width);//向左上进行搜索 search_8th(lb,a,i,j,length,width);//向右上进行搜索 } } }; 算法分析: 对矩阵每行列进行遍历,对每个位置都进行八个方向的搜索。 子搜索函数: 子搜索函数有8个,其实现较为类似,下面仅以search_1st()为例说明。 voidTrie: : search_first(CListBox&lb,char**a,intl,intw,intlength,intwidth)//下 { inti=0,j=0; charstr[100]; CStringtemp; for(i=0;i<=length;i++)//边界判断 { for(j=0;j<=length-i;j++) { str[j]=a[l+j][w];//复制字符串 } str[j]='$';//在末尾追加结束符 str[j+1]='\0'; if(1==Search(str)) { str[j]=str[j+1]; temp.Format("%s,首字母坐标: (%d,%d)末字母坐标: (%d,%d)方向为下",str,l,w,l+j-1,w);//格式化输出到ListBox中 lb.AddString(temp); } } }; 算法分析: 将矩阵中对应方向下的下一个字符复制给str,在最后加上结束符‘$’。 以便将str传给Trie: : Search()函数进行搜索。 Trie: : Search(): intTrie: : Search(char*word) {current=root->firstChild;//先将当前位置只为第一个字母 while (1) { if(*(word)==current->data) { if(current->firstChild! =NULL)//移动current,直到左孩子为NULL,则搜索成功 { current=current->firstChild; }elsereturn1; if(*(word+1)! ='\0')//在移动current的同时word的下标也在变化 { word++; }elsereturn1;当word被遍历完后,则搜索成功 } else{ if(current->nextSibling! =NULL) { current=current->nextSibling;//对每一层的右兄弟进行搜索 }elsereturn-1;//如果遍历完后仍未找到,则搜索失败 } } }; 算法分析: 在移动current的同时word的下标同时变化,搜索成功的情况如下: .word当前单词等于current所指向的Trie树单词,且current已经到达树的最末端或者word到达最末端。 搜索失败的情况如下: 对每一层的右进行遍历,如果遍历完后仍未找到相同的字母,则搜索失败。 搜索的时空复杂性分析: 对于本算法,空间复杂度显而易见,为O (1),至于时间复杂度,首先,遍历二维数组,时间复杂度为(length*width),而对于每次进行的原子搜索,时间复杂度为log(n),n为单词表总字符个数。 原子搜索每个元素进行8次。 所以整个搜索的平均时间复杂度为最大值8*(length*width)*log(n),近似等于O(n^3)。 4.3系统运行与调试 程序运行后,结果如图所示: 系统运行良好,满足了系统开发目的。 五系统评价 优点: 程序实现WSP词库的拓展,并实现用界面显示,二叉树实现的Trie树,在操纵上十分方便和简便,而且相比传统Trie树在空间上十分节省。 程序可靠性较好,程序经过多次测试,保证每一个位置,每一个方向的单词都能被查找出来。 可以通过对文件的修改来改变矩阵。 缺点: 未能实现在矩阵上高亮显示的直观表示,不能实现在窗体中直接输入矩阵,同时二叉树实现的Trie树在时间上有更多的消耗。 实验二: 复杂记事本NotePad 一NotePad的实验综述 1.1开发背景 NotePad是一个简单实用的文本编辑软件,它通过对TXT格式文件的操作来实现文本的创建和编辑。 Window操作系统为我们提供了一个功能完整的NotePad程序,具有新建,打开,保存等系统功能与复制,粘贴,剪切,撤销,查找等基本编辑功能。 然而,随着用户不断增强的对软件易用性的要求,需要记事本具有更友好的操作和功能,比如单词拼写检查和自动提示输入功能,于是,有必要开发一款功能增强型的记事本程序。 1.2问题介绍 问题描述: “记事本”是一个用来创建简单文档的文本编辑器。 “记事本”最常用来查看或编辑文本(.txt)文件,在我们开发的这个记事本中,需要支持的功能如下: 1、常规编辑,不需要支持格式; 2、支持查找的简单逻辑表达式; 3、替换特定的字符或词; 4、具有英文单词的拼写检查能力; 5、具有自动提示输入功能(仅限于英语单词)。 1.3新系统目标 NotePad的设计目标是,对原有的记事本功能进行改进。 原有的记事本程序仅实现基本的文字编辑功能,不够人性化。 新系统将大大降低操作的复杂性,实现更多的功能,增强的查找将使操作更加精确,自动提示功能极大地方便了用户的英文输入。 对NotePad的具体要求有以下几点: 1、界面必须是图形界面 2、具有英文单词的拼写检查能力; 3、具有自动提示输入功能(仅限于英语单词)。 4、关于“支持查找的简单逻辑表达式”的说明: 1)当输入一个词时,能够标记出出现这个词的所有地方; 2)当输入超过一个词时,可能会出现如下形式: a)word1word2: 代表了在一个句子中既要出现word1,也要出现word2,并且word1要先于word2; b)word1ANDword2: 代表了在一个句子中既要出现word1,也要出现word2,出现顺序无所谓; c)word1ORword2: 代表了在一个句子中要么出现word1,要么出现word2; d)word1–word2: 代表了在一个句子中必须出现word1,且word2决不能存在; e)“word1word2”: 代表了将word1word2做为一个整体看待 3)解释2)中出现的空格、AND、OR、-(减号)都做为查找表达式的运算符,且这些运算符的优先级都是一致的; 4)解释2)中出现的“句子”,表明的是搜索的基本范围的划分,在我们所编辑的文本中应该是由一个以上的句子构成,句子则是以英文的句号、问号进行分割的; 二NotePad的系统分析 2.1信息储存结构 (1)Trie树中每个节点以结构体存储: structNode{ chardata; Node*firstChild,*nextSibling; Node(charvalue='\0',Node*fc=NULL,Node*ns=NULL): data(value),firstChild(fc),nextSibling(ns){} }; (2)文本编辑的内容以CString的类型存储。 (3)为了实现单词汉语意思的输出,我们将汉语释义也放入Trie树,然后试图通过二叉树的前序遍历的来输出单词,包括其汉语意思。 但是这样做存在着无法克服的缺陷,即不能完整地将单词显示出来,通常只会显示出后缀甚至后缀的一部分。 比如: 我们输入前缀ab- 显示的结果是: ide andon reviation 为了克服
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 实现 复杂 记事本
![提示](https://static.bdocx.com/images/bang_tan.gif)