过程性保存文本格式的实现 计算概论小课题 王元康.

Slides:



Advertisements
Similar presentations
DOC 推廣活動 月餅星光大道. 中秋  農曆八月十五日,是中國傳統的中秋節。 古人將一年分成春夏秋冬四季,而一季又 分為孟、仲、季三月,八月是仲秋之月, 而十五又是這個月中間的一天,正處在秋 季的正中,所以把八月十五稱為「中秋」 或「仲秋」。  中秋夜,月亮最圓,月色最美,因此人們 把月圓看成是團圓的象徵,同時也稱八月.
Advertisements

中 五 級中 五 級 戰後國共關係 與 中華人民共和國成立 中國歷史科 1 )認識國共政治協商的概況 2 )認識國共內戰的概略經過及結果 3 )中華人民共和國成立.
不吃早餐的影響: 體內的葡萄糖無法 足夠供應給大腦與 肌肉,會感覺疲勞, 注意力無法集中。。 營養的早餐:乳品 + 全榖類食品 + 蛋白質 + 水果 早餐你吃了嗎?
人文地理專題研究 王志明.
项目6 通用堆栈.
視覺傳達設計研究所 主持人:視覺傳達設計系所長黃文勇 演講人:視覺傳達設計研究所校友 賴奕佑
2014年爱婴医院复核方案解读 省卫生计生委妇幼处 邱灵.
导言 第四 单元 凡尔赛—华盛顿体系与第二次世界大战
四資二甲 第三週作業 物件導向程式設計.
第一章 C语言概述 计算机公共教学部.
AI人工智慧報告 黑白棋 班級:資工四乙 學號:498G0009 姓名:盧冠妤.
南京理工大学 第2章 Java基本语法 本章我们将学习Java编程语言的基本语法,包括变量、操作符、表达式、语句、字符串、数组、控制流以及如何使用帮助文档。 使用下面的编程框架: public class Test{ public static void main(String []args){ //以下添加测试代码.
计算机高级程序设计 第五章.
第二章 JAVA语言基础.
第7单元 面向过程编程—— 继承与多态.
广东省教育厅教研室 吴惟粤 广州 广东教研 让每一个学生都得到充分发展 广东省普通高中 新课程实验工作介绍 广东省教育厅教研室 吴惟粤
第三章 控制结构.
第4章 需求分析 教学目的:了解需求分析的任务和步骤、评审标准和过 程,掌握基本技术,理解需求规格说明书的 作用与组成。
版本控制工具VSS.
控制流程 邏輯判斷 迴圈控制.
第四章 在 C# 中实现 OOP 概念.
第5章 图形和文本输出.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
第2章回顾 标识符:不用记,动手 关键字:if, else, switch, for, while, do, break, continue, void, …… 局部变量和成员变量 ①变量作用域 ②内存布局 基本数据类型 ①4类8种 ②互相转换 流程控制语句 ①分支 if……else, switch.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
程序设计期末复习 黎金宁
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
第5章 文本与字体 2018/12/3 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2018/12/3 Huang Weitong.
一天學會MFC 滕薇鈞
高等視窗程式設計 GUI的使用(Dialog Base) 游子宜.
第1章 Windows应用程序框架的 创建与消息处理
第十一讲 MFC常用控件的使用(3) 严宣辉 数学与计算机科学学院
MFC WinSock类的编程 为简化套接字网络编程,更方便地利用Windows的消息驱动机制,微软的基础类库(Microsoft Foundation Class Libary,简称MFC),提供了两个套接字类,在不同的层次上对Windows Socket API函数进行了封装,为编写Windows.
VC++开发实例 张荣梅 2007年2月.
Chapter6 队列(Queues) The Abstract Data Type
10 多載函數 10.1 多載概論 多載一般函數 多載成員函數 10-3
第二章 商业银行资本管理.
第三章 C# 基础知识.
VISUAL C++ 编程中的图形 图形设备接口(Graphic device interface)
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
劉崇汎 崑山科技大學 電腦與通訊系 DLL的建立與引用 劉崇汎 崑山科技大學 電腦與通訊系
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
程式結構&語法.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
《面向对象程序设计与Visual C++6.0教程》
Visual C++ Windows Programming
MFC及其应用.
程式的時間與空間 Time and Space in Programming
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
字符串 (String) 字符串是 n (  0 ) 个字符的有限序列, 记作 S = “c1c2c3…cn” 其中,S 是串名字
第5章 文本与字体 2019/4/25 面向对象与可视化 程序设计 --Visual C++ 编程 主讲教师: 唐 龙教授 (计算机科学与技术系) 黄维通博士 (计算机与信息管理中心) 清 华 大 学 2001年2月 2019/4/25 Huang Weitong.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
C++语言程序设计 C++语言程序设计 第十章 多态 第十一组 C++语言程序设计.
資料結構簡介 綠園.
本节内容 对象拷贝 视频提供:昆山爱达人信息技术有限公司.
B A C D ADD YOUR TEXT ADD YOUR TEXT ADD YOUR TEXT ADD YOUR TEXT
目标 流程控制 字符串处理 C# 的类和对象 C# 访问修饰符 C# 构造函数和析构函数.
龍老師我不會Debug QQ.
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第七章  数 组.
中式烹调技艺 第五章.
迴圈(重複性結構) for while do while.
C++语言程序设计 C++语言程序设计 第十一章 异常处理 C++语言程序设计.
本节内容 在堆中创建对象 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++程序语言设计 Chapter 14: Templates.
第二章 Java基本语法 讲师:复凡.
Presentation transcript:

过程性保存文本格式的实现 计算概论小课题 王元康

Lay Out 课题的最终目的 基础类和算法 用visual studio2010创建MFC工程 实现程序预期功能 成品展示及分析 课题总结 参考资料

课题的最终目的

课题的最终目的 课题的最终成品 一个基于核心算法的简单文本编辑器软件(用 visual studio2010和MFC框架完成) 与之配套的一个新的文件类型(prt:process recorded text) 该编辑器具有文本读写功能(只支持.prt文件)和 查看并恢复一切之前保存过的状态的功能。

基础类和算法

基础类 1,基础类 现在拥有一个文本编辑器,用户在三种条件下依保存: Abcdefghijklmnopqrstuvwxyz 保存 Abcdefghijklmnopqrstuvwxyzabc 保存 defghijklmnopqrstuvwxyzabc 保存 算法将记录三个过程对象: (0,add,” Abcdefghijklmnopqrstuvwxyz”) (26,add,”abc”) (0,del,3) 现在将这样的过程对象抽象为一个类:Changer(改变 子)类。

Changer类成员变量 Class Changer{ public: int begin_index; int type; CString a; int number; ……………… }; 有四个成员变量,begin_index标记改变的发生位置, type标记类型(添加或删除),a标记添加的内容, number标记删除的位数。

Changer类成员函数 class Changer{ ……………… public: Changer(int begin_index,CString a); Changer(int begin_index,char b); Changer(int begin_index,int number); Changer(int tpye); Changer(); Changer(Changer & c); bool isadder(); void Change(CString &d); }; 有这些成员函数:六个构造函数,isadder()判断是不 是添加,Change()对一个CString进行Changer所对应 的操作。

以上就是类的基本结构,当然,为了配合串行化对 象和MFC架构以后还要进行很多修改。

算法 将Changer修改为从CObject类继承(这也为串行 化提供支持)。 class Changer : public CObject{………………}; 将一组Changer放在MFC提供的容器CObArray之 中。

recover CString recover(CObArray *pmemory,int end_index,CString a){ if(-1==end_index||end_index>=pmemory->GetSize()){ end_index=pmemory->GetSize(); } //第二、三个参数使用默认值调用的时候,从空状态恢复所所有的。 CString b=a; for(int i=0;i<end_index;i++){ reinterpret_cast<Changer *>(pmemory->GetAt(i))- >Change(b);//这个转换应该没大问题,因为memory里的指针是 Changer转过去的。 return b; 我们可以实现对CString对象的连续操作。 通过recover这个函数来实现,他需要提供一个CObArray指针 pmemory(包含一列Changer),实际进行的操作数end_index(默认 是全部执行),和初始值(默认为空CString)。

seek_change //先实现这个函数 int get_char_index(CString a,char x,int begin_index){ int length=a.GetLength(); for(int i=begin_index;i<length;i++){ if(a[i]==x) return i; } return length; }//在字符串a中寻找x,从指标begin_index开始。 未达返回length

CObArray * seek_change(CString b,CString a){ int length=min(a.GetLength(),b.GetLength()); CString temp_string; CObArray *pmemory=new CObArray; for(int i=0;i<length;i++){ if(a[i]!=b[i]){//获取上下文搜索到的指标,a 是上文,b是下文。 int status1=get_char_index(a,b[i],i);// 在上文中搜索 int status2=get_char_index(b,a[i],i); //在下文中搜索

if(status1==a.GetLength()&&status2==b.GetLength()) { Changer* pc=new Changer(i,b[i]); pmemory->Add(pc); pc->Change(a); } else if(status1<=status2){//如果上文搜索得到 的指标更小,就将上文搜索过的元素去除。 Changer *pc=new Changer(i,status1-i); else{//如果下文搜索得到的指标更小,就将下文搜 索过的元素添加。 Changer* pc=new Changer(i,b.Mid(i,status2-i)); }}}

if(a.GetLength()>b.GetLength()){//以下两个判断处 理多余的长度 Changer* pc=new Changer(length,int(a.GetLength()-length)); pmemory->Add(pc); pc->Change(a); } else if(a.GetLength()<b.GetLength()){ Changer* pc=new Changer(length,b.Right(b.GetLength()-length)); simplify(pmemory);//这里产生完之后要化简,化 简函数在下方会给出。 return pmemory;

simplify void simplify(CObArray *pmemory){ for(int i=pmemory->GetSize()-1;i>0;i--){ //第一类化简,共点删除。 while(1){ if(i==pmemory->GetSize()){ break; } Changer* ci=reinterpret_cast<Changer*>(pmemory- >GetAt(i)); Changer* ci_1=reinterpret_cast<Changer*>(pmemory- >GetAt(i-1));

if((ci->begin_index==ci_1- >begin_index)&&((ci->type)&&(ci_1->type))){ Changer* pc=new Changer(*ci_1); pc->number=ci- >number+ci_1->number; //释放堆内存 delete ci; delete ci_1; pmemory->RemoveAt(i- 1,2); pmemory->InsertAt(i-1,pc); } else{ break;

//第二类化简,连续加合并。PS:不可能和上一个 同时触发 while(1){ if(i==pmemory->GetSize()){ break; } Changer* ci=reinterpret_cast<Changer*>(pmemory- >GetAt(i)); Changer* ci_1=reinterpret_cast<Changer*>(pmemory- >GetAt(i-1));

if(!(ci->type||ci_1->type)&&(ci- >begin_index-ci_1->begin_index==ci_1- >a.GetLength())){ Changer* pc=new Changer(*ci_1); pc->a=ci_1->a+ci->a; pmemory->RemoveAt(i- 1,2); pmemory->InsertAt(i-1,pc); } else{ break;

以上三个算法便是主体算法了,构建完基础类和主 体算法就可以用visual studio2010建立MFC框架 应用程序了。

用visual studio2010创建MFC工程

visual studio2010 是一个支持多文档、多窗口的应用程序,功能很强 大,拥有强大debug能力和图形化编程支持。

MFC MFC是微软提供的应用程序开发框架,它分为单文 档支持和多文档支持,采用文档、框架、视类三部 分(每部分对应一个类)来构建一个文件处理的应 用程序(当然图形处理、网页处理也是文件处理)。 类与类之间用类方法链接。主要的基类有: CDocument、CMainFrm、CWinApp、CView。 然后用户从这些类上派生的类便拥有基本的文件处 理手段。

实现程序预期功能

应用程序架构

首先,test.h中定义了CtsetApp类,继承 自CWinAppEx类。 testDoc.h中定义了CtestDoc类,继承自 CDocument。 testView.h中定义了CtestView类,继承自 CEditView,CEditView继承自CView并附 带了简单的文本处理功能。 Changer.h中定义了Changer类和与 Changer类相关的非成员函数 。 RecoverDlg.h中定义了CRecoverDlg类, 继承自CDialogEx类,它是程序中的第二 个窗口,可通过按钮调出并实现恢复文件 的功能。

Changer类的串行化支持以及数据的的存取 //Changer.h class Changer : public CObject { public: ……………… DECLARE_SERIAL(Changer); void Serialize(CArchive& ar); }; //Changer.cpp IMPLEMENT_SERIAL(Changer,CObject,1); void Changer::Serialize(CArchive& ar){ if(ar.IsStoring()){ ar<<begin_index<<type<<a<<number; } else{ ar>>begin_index>>type>>a>>number;

这样我们就能用CArchive对向来读取和保存文件中 的Changer数据。由于CObArray本身支持串行化, 故可以建立一个CObArray *变量来保存两次修改 之间的所有的Changer,并在CtestDoc类建立一 个CObArray *类型的成员变量m_pallmemory来 保存所有的CObArray *。 然后在Serialize函数中实现保存和读取。

void CtestDoc::Serialize(CArchive& ar) { if(ar.IsStoring()){//如果是存储过程 CString temp; //这里要先get以下view POSITION pos=GetFirstViewPosition(); GetNextView(pos)->GetWindowTextA(temp); CObArray * new_pmemory;//new_pmemory用以储存 两次保存之间的Changer。 new_pmemory=seek_change(temp,m_content); if(0!=new_pmemory->GetSize()){ m_pallmemory->Add(new_pmemory); //将new_pmemory压入m_pallmemory } //刷新m_isnew m_isnew=false; m_content=temp;//将这个内容刷新为下一次保存做准 备 m_pallmemory->Serialize(ar);//调用CObArray的 Serialize函数保存数据。

else{ //如果是读取内容 m_pallmemory->Serialize(ar);//调用 CObArray的Serialize函数读取数据。 int nSave=m_pallmemory->GetSize(); for(int i=0;i<nSave;i++){ m_content=recover(reinterpret_cast<CObArra y *>(m_pallmemory->GetAt(i)),-1,m_content); } //这里也要get一次view。 POSITION pos=GetFirstViewPosition(); GetNextView(pos)- >SetWindowTextA(m_content); //刷新m_isnew m_isnew=false;

创建Dialog并响应消息 一个Dialog(对话框), 包含三种控件,左边的 是List Box,对应的控 制类是CListBox,我在 CRecoverDlg类创建了 一个CListBox类型的成 员变量m_listctrl来控制 它。右边是一个Edit Control,我没有使用 他的control对象而是创 建了一个CString类对象 来绑定它的文本。最下 面是三个按钮

List Box的处理 首先在CRecoverDlg::OnPaint中获取CtestDoc中的数据并绘制 列表。 void CRecoverDlg::OnPaint() { CPaintDC dc(this); // device context for painting // TODO: 在此处添加消息处理程序代码 // 不为绘图消息调用 CDialogEx::OnPaint() if(!m_painted){ //这些主要是获取Doc类的指针(Doc类就是指CtestDoc类, 下同)。 CMainFrame* pFrame=(CMainFrame*)AfxGetMainWnd(); CtestView* pView = (CtestView*)pFrame- >GetActiveView(); CtestDoc *doc=pView->GetDocument();

int nSave=doc->m_pallmemory->GetSize(); for(int i=0;i<nSave-1;i++){ char a[10]; m_listctrl.InsertString(0,_itoa(i- nSave+1,a,10));//InsertString在指定位置添加字符串。 } m_listctrl.InsertString(0,"当前状态"); m_context=m_nowtext;// View类在调用Dialog之前 将现在屏幕数据保存在n_nowtext中,此时作为文本提示的 默认值,也是当前状态的值。 UpdateData(false);//将m_context的改变load一下。 m_painted=true;

之后,添加对ListBox项点击的消息处理函数 void CRecoverDlg::OnLbnSelchangeList1() { // TODO: 在此添加控件通知处理程序代码 int n=m_listctrl.GetCount()- m_listctrl.GetCurSel();//FetCurSel获取选中索引号。 if(1!=m_listctrl.GetCount()){ if(0!=m_listctrl.GetCurSel()){ CMainFrame* pFrame=(CMainFrame*)AfxGetMainWnd(); CtestView* pView = (CtestView*)pFrame->GetActiveView(); CtestDoc *doc=pView- >GetDocument(); CString temp; for(int i=0;i<n;i++){ temp=recover(reinterpret_cast<CObArray *>(doc->m_pallmemory->GetAt(i)),-1,temp); }//计算第n次保存之后的文档内容

GetDlgItem(IDC_TEXT)- >SetWindowTextA(temp);//将文档内容显示 //这里也可以m_context=doc- >m_content;UpdateData(false);load数据 } else{ GetDlgItem(IDC_TEXT)- >SetWindowTextA(m_nowtext);//第一个单独画吧 CMainFrame* pFrame=(CMainFrame*)AfxGetMainWnd(); CtestView* pView = (CtestView*)pFrame- >GetActiveView(); CtestDoc *doc=pView->GetDocument(); GetDlgItem(IDC_TEXT)- >SetWindowTextA(m_nowtext); //m_context=doc->m_content; //UpdateData(false);

对于三个CButton的逻辑设计 第一个,舍弃之后代表我要恢复到在List Box中选 中的这个状态,并且将自己已经进行的在该状态之 后的改变全部抛弃。 第二个,保留之后代表我要恢复到在List Box中选 中的这个状态,是以添加一个从现状算到选中状态 的过程来实现的。 第三个,取消就是什么都不做(不响应)。

在使用Dialog前要求用户保存文件 最后我们在调用Dialog前用n_isnew标签来判断是 否为新建的文档,如果是要求用户保存(否则恢复 功能将没有意义)

成品展示及分析

成品展示 现场展示 不贴图了

分析 通过改变子的迭代实现了过程性保存的功能,可能 存在bug,但是日常使用压力不大。 文件的大小的方面,上面的文件最后有4kb,直接 用记事本保存需要1kb。

课题总结 基本实现了课题的预期。 通过本课题,我的收获了使用 visual studio2010和MFC编程的 技巧,同时实现了原创算法。

参考资料: [1] MSDN中文网页版 https://msdn.microsoft.com/query/dev10.query? appId=Dev10IDEF1&l=ZH- CN&k=k(MSDNSTART)&rd=true [2] MFC视频教程全集 作者:孙鑫 http://v.dxsbb.com/jisuanji/555/

谢谢