∪∩deniable Design

个人JAVA版GAE(google app engine),struts2+jpa+jQuery开发,互相交流 http://iunbug.appspot.com/
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

《数据结构》实训报告

文章编辑器

NoteLite

 

姓名: ∪∩BUG

                                                        学号:                                                                        指导老师:    

                                                                

 

    

目 录

  1. 实训目的    ………………………………………….. ………………………………………….. ……….. ….1
  2. 需求分析    ………………………………………….. ………………………………………….. ……….. ….1
  3. 文章编辑器NoteLite简介    ………………………………………………………….. ……….. …1
  4. 设计概要    
    1. 主要控件    ………………………………………….. ………………………………………….. ……….. ….1
    2. 流程图        ………………………………………….. ………………………………………….. ……….. ….2
  5. 详细设计    ………………………………………….. ………………………………………….. ……….. ….3
  6. 使用说明    ………………………………………….. ………………………………………….. ……….. ….17
  7. 心得        ………………………………………….. ………………………………………….. ……….. ….21
  8. 参考书目    ………………………………………….. ………………………………………….. ……….. ….21

    (CTRL+左键可快速转到相应的页码)

        

 

文章编辑器NoteLite

  1. 实训目的

运用VC++6.0 通过MFC开发基于对话框的文章编辑器NoteLite,其中运用数据结构中的模式匹配Brute Froce算法来实现匹配,删除和替换功能。并实现文章编辑器NoteLite的数字及字符的统计等一般的操作。

 

    本程序演示用C++编写,完成MFC创建的文章编辑器NoteLite,Brute Froce算法来实现匹配,删除和替换功能。并统计主编辑框的字符总数,数字总数,空格总数,字母个数及与测试编辑框的内容匹配的总数和文章的总行数,能对相应的操作进行无限撤消和无限重做。

输入值的范围:主编辑框,测试编辑框,替换编辑框均可输入任意字符。在插入字符时要求测试编辑框的内容的长度加上主编辑框的内容的长度不超过主编辑框长度的允许范围。在替换字符时要求替换后主编辑框的内容长度不能超过主编辑框长度的允许范围。

输出形式:统计的结果会在相应的编辑框显示,其中行数和字符个数即时显示。

测试数据

A    要主编辑框中输入:文章编辑器 V1.0 Beta

    得到字符总数20,行数1.统计后得到字母个数5,空格个数2,数字个数2.

B    在测试编辑框中输入:文章编辑器

    单击匹配得匹配次数1,单击删除主编辑框的内容变为"V1.0 Beta",单击插入主编辑框恢复"文章编辑器 V1.0 Beta"。

C    在替换编辑框中输入:NoteLite

    单击替换主编辑框的内容变为"NoteLite V1.0 Beta"

D    单击清空主编辑框的内容被清空,单击撤消变为"文章编辑器 V1.0 Beta",单击重做主编辑框的内容再被清空。

 

    文章编辑器NoteLite运行于Windows下,主要实现文本的输入,一般的编辑操作,如:插入,删除,撤消,重做。能查找特定字符在文本中出现的字数,并能批量删除或替换特定的字符串,能对输入的文本进行字符总数,行数,字母个数,数字个数,空格个数。

 

(1)为了实现文章编辑器NoteLite上述的功能,需要建立的控件有:

    1.    编辑框控件(10):

        主编辑框            IDC_EDIT2;

测试编辑框        IDC_EDIT1;

        替换编辑框        IDC_EDIT4;

        显示行数            IDC_EDIT3;

        显示字符总数        IDC_EDIT5;

        显示字母个数        IDC_EDIT6;

        显示数字个数        IDC_EDIT7;

显示空格个数        IDC_EDIT8;

显示匹配次数        IDC_EDIT9;

显示匹配次数        IDC_EDIT10;

    2.    按扭控件(9)

插入                IDC_INSERT_BUTTON

删除                IDC_DEL_BUTTON

匹配                IDC_MATCH_BUTTON

替换                 IDC_REPLACE_BUTTON

统计                IDC_COUNT_BUTTON

清空                 IDC_CLEAR_BUTTON

撤消                 IDC_UNDO_BUTTON

重做                 IDC_REDO_BUTTON

退出                 IDC_CANCEL_BUTTON2

    3.    静态编辑框若干个

(2) 流程图

    1.    匹配算法(Brute Froce算法)

  1. 详细设计
      1// NoteLiteDlg.h : header file
      2//
      3
      4#if !defined(AFX_NOTELITEDLG_H__10C7DDD7_EB75_4AAD_9498_533D9CAAEAC5__INCLUDED_)
      5#define AFX_NOTELITEDLG_H__10C7DDD7_EB75_4AAD_9498_533D9CAAEAC5__INCLUDED_
      6
      7#if _MSC_VER > 1000
      8#pragma once
      9#endif // _MSC_VER > 1000
     10
     11/////////////////////////////////////////////////////////////////////////////
     12// CNoteLiteDlg dialog
     13
     14class CNoteLiteDlg : public CDialog
     15{
     16// Construction
     17public:
     18    int undoNum;            //撤消计数器
     19    int doNum;                //操作计数器
     20    CString CurText[1000];    //当前主编辑框内容
     21    CString PreText[1000];    //之前主编辑框内容
     22    BOOL CheckFocus;        //测试编辑框焦点检测
     23    CNoteLiteDlg(CWnd* pParent = NULL);    // standard constructor
     24
     25// Dialog Data
     26    //{{AFX_DATA(CNoteLiteDlg)
     27    enum { IDD = IDD_NOTELITE_DIALOG };
     28    CEdit    m_Time;
     29    CEdit    m_Replace;
     30    CEdit    m_Match;
     31    CEdit    m_TDigitNum;
     32    CEdit    m_TSpaceNum;
     33    CEdit    m_TLetterNum;
     34    CEdit    m_Check;
     35    CEdit    m_Main;
     36    CEdit    m_TCharNum;
     37    CEdit    m_TLine;
     38    //}}AFX_DATA
     39
     40    // ClassWizard generated virtual function overrides
     41    //{{AFX_VIRTUAL(CNoteLiteDlg)
     42    protected:
     43    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
     44    //}}AFX_VIRTUAL
     45
     46// Implementation
     47protected:
     48    BOOL MainFocus;        //主编辑框焦点检测
     49    HICON m_hIcon;
     50
     51    // Generated message map functions
     52    //{{AFX_MSG(CNoteLiteDlg)
     53    virtual BOOL OnInitDialog();
     54    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
     55    afx_msg void OnPaint();
     56    afx_msg HCURSOR OnQueryDragIcon();
     57    afx_msg void OnCancelButton2();
     58    afx_msg void OnChangeEdit2();
     59    afx_msg void OnSetfocusEdit1();
     60    afx_msg void OnSetfocusEdit2();
     61    afx_msg void OnInsertButton();
     62    afx_msg void OnClearButton();
     63    afx_msg void OnCountButton();
     64    afx_msg void OnDelButton();
     65    afx_msg void OnUndoButton();
     66    afx_msg void OnRedoButton();
     67    afx_msg void OnMatchButton();
     68    afx_msg void OnReplaceButton();
     69    afx_msg void OnChangeEdit3();
     70    //}}AFX_MSG
     71    DECLARE_MESSAGE_MAP()
     72}
    ;
     73
     74//{{AFX_INSERT_LOCATION}}
     75// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
     76
     77#endif // !defined(AFX_NOTELITEDLG_H__10C7DDD7_EB75_4AAD_9498_533D9CAAEAC5__INCLUDED_)
     78
     79// NoteLiteDlg.cpp : implementation file
     80//
     81
     82#include "stdafx.h"
     83#include "NoteLite.h"
     84#include "NoteLiteDlg.h"
     85
     86#ifdef _DEBUG
     87#define new DEBUG_NEW
     88#undef THIS_FILE
     89static char THIS_FILE[] = __FILE__;
     90#endif
     91
     92/////////////////////////////////////////////////////////////////////////////
     93// CAboutDlg dialog used for App About
     94
     95class CAboutDlg : public CDialog
     96{
     97public:
     98    CAboutDlg();
     99
    100// Dialog Data
    101    //{{AFX_DATA(CAboutDlg)
    102    enum { IDD = IDD_ABOUTBOX };
    103    //}}AFX_DATA
    104
    105    // ClassWizard generated virtual function overrides
    106    //{{AFX_VIRTUAL(CAboutDlg)
    107    protected:
    108    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    109    //}}AFX_VIRTUAL
    110
    111// Implementation
    112protected:
    113    //{{AFX_MSG(CAboutDlg)
    114    //}}AFX_MSG
    115    DECLARE_MESSAGE_MAP()
    116}
    ;
    117
    118CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
    119{
    120    //{{AFX_DATA_INIT(CAboutDlg)
    121    //}}AFX_DATA_INIT
    122}

    123
    124void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    125{
    126    CDialog::DoDataExchange(pDX);
    127    //{{AFX_DATA_MAP(CAboutDlg)
    128    //}}AFX_DATA_MAP
    129}

    130
    131BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    132    //{{AFX_MSG_MAP(CAboutDlg)
    133        // No message handlers
    134    //}}AFX_MSG_MAP
    135END_MESSAGE_MAP()
    136
    137/////////////////////////////////////////////////////////////////////////////
    138// CNoteLiteDlg dialog
    139
    140CNoteLiteDlg::CNoteLiteDlg(CWnd* pParent /*=NULL*/)
    141    : CDialog(CNoteLiteDlg::IDD, pParent)
    142{
    143    doNum = 0;        //初始化之前的操作计数器
    144    undoNum = 0;    //初始化撤消的操作计数器
    145
    146    //{{AFX_DATA_INIT(CNoteLiteDlg)
    147    //}}AFX_DATA_INIT
    148    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    149    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    150}

    151
    152void CNoteLiteDlg::DoDataExchange(CDataExchange* pDX)
    153{
    154    CDialog::DoDataExchange(pDX);
    155    //{{AFX_DATA_MAP(CNoteLiteDlg)
    156    DDX_Control(pDX, IDC_EDIT10, m_Time);
    157    DDX_Control(pDX, IDC_EDIT4, m_Replace);
    158    DDX_Control(pDX, IDC_EDIT9, m_Match);
    159    DDX_Control(pDX, IDC_EDIT7, m_TDigitNum);
    160    DDX_Control(pDX, IDC_EDIT8, m_TSpaceNum);
    161    DDX_Control(pDX, IDC_EDIT6, m_TLetterNum);
    162    DDX_Control(pDX, IDC_EDIT1, m_Check);
    163    DDX_Control(pDX, IDC_EDIT2, m_Main);
    164    DDX_Control(pDX, IDC_EDIT5, m_TCharNum);
    165    DDX_Control(pDX, IDC_EDIT3, m_TLine);
    166    //}}AFX_DATA_MAP
    167}

    168
    169BEGIN_MESSAGE_MAP(CNoteLiteDlg, CDialog)
    170    //{{AFX_MSG_MAP(CNoteLiteDlg)
    171    ON_WM_SYSCOMMAND()
    172    ON_WM_PAINT()
    173    ON_WM_QUERYDRAGICON()
    174    ON_BN_CLICKED(IDC_CANCEL_BUTTON2, OnCancelButton2)
    175    ON_EN_CHANGE(IDC_EDIT2, OnChangeEdit2)
    176    ON_EN_SETFOCUS(IDC_EDIT1, OnSetfocusEdit1)
    177    ON_EN_SETFOCUS(IDC_EDIT2, OnSetfocusEdit2)
    178    ON_BN_CLICKED(IDC_INSERT_BUTTON, OnInsertButton)
    179    ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton)
    180    ON_BN_CLICKED(IDC_COUNT_BUTTON, OnCountButton)
    181    ON_BN_CLICKED(IDC_DEL_BUTTON, OnDelButton)
    182    ON_BN_CLICKED(IDC_UNDO_BUTTON, OnUndoButton)
    183    ON_BN_CLICKED(IDC_REDO_BUTTON, OnRedoButton)
    184    ON_BN_CLICKED(IDC_MATCH_BUTTON, OnMatchButton)
    185    ON_BN_CLICKED(IDC_REPLACE_BUTTON, OnReplaceButton)
    186    ON_EN_CHANGE(IDC_EDIT3, OnChangeEdit3)
    187    //}}AFX_MSG_MAP
    188END_MESSAGE_MAP()
    189
    190/////////////////////////////////////////////////////////////////////////////
    191// CNoteLiteDlg message handlers
    192
    193BOOL CNoteLiteDlg::OnInitDialog()
    194{
    195    CDialog::OnInitDialog();
    196
    197    // Add "About" menu item to system menu.
    198
    199    // IDM_ABOUTBOX must be in the system command range.
    200    ASSERT((IDM_ABOUTBOX & 0xFFF0== IDM_ABOUTBOX);
    201    ASSERT(IDM_ABOUTBOX < 0xF000);
    202
    203    CMenu* pSysMenu = GetSystemMenu(FALSE);
    204    if (pSysMenu != NULL)
    205    {
    206        CString strAboutMenu;
    207        strAboutMenu.LoadString(IDS_ABOUTBOX);
    208        if (!strAboutMenu.IsEmpty())
    209        {
    210            pSysMenu->AppendMenu(MF_SEPARATOR);
    211            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    212        }

    213    }

    214
    215    // Set the icon for this dialog.  The framework does this automatically
    216    //  when the application's main window is not a dialog
    217    SetIcon(m_hIcon, TRUE);            // Set big icon
    218    SetIcon(m_hIcon, FALSE);        // Set small icon
    219    
    220    // TODO: Add extra initialization here
    221    
    222    return TRUE;  // return TRUE  unless you set the focus to a control
    223}

    224
    225void CNoteLiteDlg::OnSysCommand(UINT nID, LPARAM lParam)
    226{
    227    if ((nID & 0xFFF0== IDM_ABOUTBOX)
    228    {
    229        CAboutDlg dlgAbout;
    230        dlgAbout.DoModal();
    231    }

    232    else
    233    {
    234        CDialog::OnSysCommand(nID, lParam);
    235    }

    236}

    237
    238// If you add a minimize button to your dialog, you will need the code below
    239//  to draw the icon.  For MFC applications using the document/view model,
    240//  this is automatically done for you by the framework.
    241
    242void CNoteLiteDlg::OnPaint() 
    243{
    244    if (IsIconic())
    245    {
    246        CPaintDC dc(this); // device context for painting
    247
    248        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
    249
    250        // Center icon in client rectangle
    251        int cxIcon = GetSystemMetrics(SM_CXICON);
    252        int cyIcon = GetSystemMetrics(SM_CYICON);
    253        CRect rect;
    254        GetClientRect(&rect);
    255        int x = (rect.Width() - cxIcon + 1/ 2;
    256        int y = (rect.Height() - cyIcon + 1/ 2;
    257
    258        // Draw the icon
    259        dc.DrawIcon(x, y, m_hIcon);
    260    }

    261    else
    262    {
    263        CDialog::OnPaint();
    264    }

    265}

    266
    267// The system calls this to obtain the cursor to display while the user drags
    268//  the minimized window.
    269HCURSOR CNoteLiteDlg::OnQueryDragIcon()
    270{
    271    return (HCURSOR) m_hIcon;
    272}

    273
    274//退出函数
    275void CNoteLiteDlg::OnCancelButton2() 
    276{
    277    OnOK();    
    278}

    279
    280//主编辑框更新函数
    281void CNoteLiteDlg::OnChangeEdit2() 
    282{
    283    CString MText;        //主编辑框内容    
    284    char Count[6];        //统计
    285    int CharNum;        //字符总个数
    286    int LineNum;        //主编辑框的行数
    287
    288        m_Main.GetWindowText(MText);    //获得主编辑框内容保存入MText
    289        CharNum = MText.GetLength();        //取得字符串长度
    290        LineNum = m_Main.GetLineCount();    //取得行数
    291        CharNum -= (LineNum-1);            //减去换行产生的字符
    292        itoa(CharNum,Count,10);    //将整形CharNum转换为字符串保存在Count中
    293        m_TCharNum.SetWindowText(Count);    //显示字符数
    294        itoa(LineNum,Count,10);    //将整形LineNum转换为字符串保存在Count中
    295        m_TLine.SetWindowText(Count);            //显示行数
    296
    297    
    298    
    299    //当光标移置主编辑框时
    300    if(MainFocus && !CheckFocus && doNum < 1000)
    301    {
    302        //将之前主编辑框时的内容保存
    303        m_Main.GetWindowText(PreText[doNum]);
    304        doNum++;
    305    }
     
    306        
    307}

    308
    309//测试编辑框的焦点函数
    310void CNoteLiteDlg::OnSetfocusEdit1() 
    311{
    312    MainFocus = FALSE;        //主编辑框失去焦点
    313    CheckFocus = TRUE;        //测试编辑框得到焦点
    314
    315    //显示时间
    316    CTime   tnow;
    317    tnow = CTime::GetCurrentTime();  
    318    CString   snow;
    319    snow = tnow.Format("%A %B %d %Y");   
    320    m_Time.SetWindowText(snow); 
    321    
    322}

    323
    324//主编辑框的焦点函数
    325void CNoteLiteDlg::OnSetfocusEdit2() 
    326{
    327    MainFocus = TRUE;            //主编辑框得到焦点
    328    CheckFocus = FALSE;        //测试编辑框失去焦点    
    329}

    330
    331//插入函数
    332void CNoteLiteDlg::OnInsertButton() 
    333{    
    334    if(doNum < 1000)
    335    {
    336        //将之前主编辑框时的内容保存
    337        m_Main.GetWindowText(PreText[doNum]);
    338        doNum++;
    339    }

    340
    341    m_Check.SetSel(0,-1);        //选中测试框的全部内容
    342    m_Check.Copy();            //复制到剪贴版
    343    m_Main.Paste();                //粘贴入主编辑框    
    344}

    345
    346//清空函数
    347void CNoteLiteDlg::OnClearButton() 
    348{
    349    if(doNum < 1000)
    350    {
    351        //将之前主编辑框时的内容保存
    352        m_Main.GetWindowText(PreText[doNum]);
    353        doNum++;
    354    }

    355
    356    
    357    m_Main.SetSel(0,-1);        //选中主编辑框的所有内容
    358    m_Main.Clear();            //清空所有内容
    359    
    360}

    361
    362
    363//统计函数
    364void CNoteLiteDlg::OnCountButton() 
    365{    
    366    CString MText;                //主编辑框内容    
    367    char Count[6];                //统计
    368    int LetterNum = 0;            //字母个数
    369    int DigitNum = 0;            //数字个数
    370    int SpaceNum = 0;            //空格个数
    371    int i = 0;                        //主编辑框的下标
    372    
    373    m_Main.GetWindowText(MText);        //获得主编辑框内容保存入MText
    374
    375    while( i != MText.GetLength())
    376    {
    377        //统计字母个数
    378        if( (MText[i] >= 'a' && MText[i] <= 'z'|| (MText[i] >= 'A' && MText[i] <= 'Z'))
    379                LetterNum++;
    380        
    381        //统计数字个数
    382        else if(MText[i] >= '0' && MText[i] <= '9')
    383            DigitNum++;
    384        
    385        //统计空格个数
    386        else if(MText[i] == ' ')
    387            SpaceNum++;
    388
    389        else;
    390            
    391        i++;
    392    }

    393
    394    itoa(LetterNum,Count,10); //将整形LetterNum转换为字符串保存在Count中
    395    m_TLetterNum.SetWindowText(Count);            //显示字母个数
    396    itoa(DigitNum,Count,10);    //将整形NumberNum转换为字符串保存在Count中
    397    m_TDigitNum.SetWindowText(Count);            //显示数字个数
    398    itoa(SpaceNum,Count,10);//将整形LineNum转换为字符串保存在Count中
    399    m_TSpaceNum.SetWindowText(Count);            //显示空格个数
    400
    401}

    402
    403//删除函数(Brute Force算法)
    404void CNoteLiteDlg::OnDelButton() 
    405{
    406    CString CText;                        //测试编辑框的内容
    407    CString MText;                        //主编辑框内容
    408    int i = 0;                                //主编辑框的下标
    409    int j = 0;                                //测试编辑框下的标
    410    int pos = 0;                            //开始删除的起始位置
    411
    412    m_Main.GetWindowText(MText);        //获得主编辑框的内容
    413    m_Check.GetWindowText(CText);        //获得测试框的内容
    414
    415    //主编辑框和测试框有内容时进行删除
    416    if ((MText.GetLength() != 0&& (CText.GetLength() != 0))
    417    {
    418        m_Main.GetWindowText(MText);        //获得主编辑框的内容
    419        m_Check.GetWindowText(CText);        //获得测试框的内容
    420
    421        while (i < MText.GetLength() && MText.GetLength() != 0 )
    422        {
    423            m_Main.GetWindowText(MText);        //获得主编辑框的内容
    424            m_Check.GetWindowText(CText);        //获得测试框的内容
    425            
    426            while ( j < CText.GetLength() && i < MText.GetLength())
    427            {
    428                if (MText[i] == CText[j])
    429                {
    430                    i++;
    431                    j++;
    432                }

    433
    434                else
    435                {
    436                    i = i - j + 1;            //主编辑框的下标回退
    437                    j = 0;                //测试编辑框的下标回退
    438                }

    439            }
                
    440            
    441            if (j == CText.GetLength()) 
    442            {
    443                pos = i - j;                            //记录开始删除的起始位置
    444                m_Main.SetFocus();
    445                m_Main.SetSel(pos,i);                //选中匹配的子串
    446                m_Main.ReplaceSel("");                //删除匹配的子串
    447                j = 0;                                //测试编辑框的下标回退
    448
    449                m_Main.GetWindowText(MText);        //获得主编辑框的内容
    450                m_Check.GetWindowText(CText);        //获得测试框的内容
    451
    452                i = i;                                //重新定位主编辑框的下标
    453
    454
    455            }

    456
    457        }

    458    }
        
    459}

    460
    461
    462//撤消函数
    463void CNoteLiteDlg::OnUndoButton() 
    464{
    465    if(undoNum < 1000)
    466    {
    467        //保存当前主编辑框的内容
    468        m_Main.GetWindowText(CurText[undoNum]);
    469        undoNum++;    
    470    }

    471
    472    if(doNum > 0)
    473    {
    474        //显示之前的文本
    475        m_Main.SetWindowText(PreText[doNum-1]);
    476        doNum--;
    477    }

    478}

    479
    480//重做函数
    481void CNoteLiteDlg::OnRedoButton() 
    482{
    483    if(undoNum > 0)
    484    {
    485        //显示当前的文本
    486        m_Main.SetWindowText(CurText[undoNum-1]);
    487        undoNum--;
    488        doNum++;
    489    }

    490    
    491}

    492
    493//匹配函数(Brute Force算法)
    494void CNoteLiteDlg::OnMatchButton() 
    495{
    496    CString CText;                    //测试编辑框的内容
    497    CString MText;                    //主编辑框内容
    498    int i = 0;                            //主编辑框的下标
    499    char Count[6];                    //统计
    500    int MatchNum = 0;                //匹配次数
    501    int j = 0;                            //测试编辑框下标
    502
    503    m_Main.GetWindowText(MText);    //获得主编辑框的内容
    504    m_Check.GetWindowText(CText);    //获得测试框的内容
    505
    506    //主编辑框和测试框有内容时进行匹配运算
    507    if ((MText.GetLength() != 0&& (CText.GetLength() != 0))
    508    {
    509        while (i < MText.GetLength())
    510        
    511            while ( j < CText.GetLength() && i < MText.GetLength())
    512            {
    513                if (MText[i] == CText[j])
    514                {
    515                    i++;
    516                    j++;
    517                }

    518
    519                else
    520                {
    521                    i = i - j + 1;            //主编辑框的下标回退
    522                    j = 0;                //测试编辑框的下标回退
    523                }

    524            }

    525
    526            if (j == CText.GetLength()) 
    527            {
    528                MatchNum++;                //匹配的次数自加
    529                j = 0;                        //测试编辑框的下标回退
    530            }

    531        }

    532    }

    533
    534//将整形MatchNum转换为一个字符串,并将值保存在Count中
    535    itoa(MatchNum,Count,10);            
    536    m_Match.SetWindowText(Count);        //显示匹配次数
    537
    538    
    539}

    540
    541
    542//替换函数(Brute Force算法)
    543void CNoteLiteDlg::OnReplaceButton() 
    544{
    545    CString CText;                    //测试编辑框的内容
    546    CString MText;                    //主编辑框的内容
    547    CString RText;                    //替换编辑框的内容
    548    int i = 0;                            //主编辑框的下标
    549    int j = 0;                            //测试编辑框下标
    550    int pos = 0;                        //开始替换的起始位置
    551
    552    m_Main.GetWindowText(MText);    //获得主编辑框的内容
    553    m_Check.GetWindowText(CText);    //获得测试框的内容
    554    m_Replace.GetWindowText(RText);    //获得替换编辑框的内容
    555    
    556
    557    //主编辑框,测试框的替换框有内容时进行替换
    558    if ((MText.GetLength() != 0&& (CText.GetLength() != 0&& (RText.GetLength() != 0))
    559    {
    560        m_Main.GetWindowText(MText);        //获得主编辑框的内容
    561        m_Check.GetWindowText(CText);        //获得测试框的内容
    562        m_Replace.GetWindowText(RText);        //获得替换编辑框的内容
    563        
    564        while (i < MText.GetLength())
    565        
    566            m_Main.GetWindowText(MText);        //获得主编辑框的内容
    567            m_Check.GetWindowText(CText);        //获得测试框的内容
    568            m_Replace.GetWindowText(RText);        //获得替换编辑框的内容
    569
    570            while ( j < CText.GetLength() && i < MText.GetLength() )
    571            {
    572                if (MText[i] == CText[j] )
    573                {
    574                    i++;
    575                    j++;
    576                }

    577
    578                else
    579                {
    580                    i = i - j + 1;            //主编辑框的下标回退
    581                    j = 0;                //测试编辑框的下标回退
    582                }

    583            }

    584
    585            if (j == CText.GetLength()) 
    586            {
    587                pos = i - j;                            //记录开始替换的起始位置
    588                m_Main.SetSel(pos,i);                //选中匹配的子串
    589                m_Main.ReplaceSel(RText);            //替换匹配的子串
    590                j = 0;                                //测试编辑框的下标回退
    591
    592                m_Main.GetWindowText(MText);        //获得主编辑框的内容
    593                m_Check.GetWindowText(CText);        //获得测试框的内容
    594                m_Replace.GetWindowText(RText);        //获得替换编辑框的内容
    595
    596                //当替换的文本比被替换的文本长时重新定位主编辑框的下标
    597                if(CText.GetLength() < RText.GetLength())
    598                    i = i + RText.GetLength() - CText.GetLength();
    599                
    600                //当替换的文本比被替换的文本短时重新定位主编辑框的下标
    601                else if(CText.GetLength() > RText.GetLength())
    602                    i = i + RText.GetLength() - CText.GetLength();
    603
    604                //当替换的文本与被替换的文本等长时重新定位主编辑框的下标
    605                else if(CText.GetLength() == RText.GetLength())
    606                    i = i;
    607                else;
    608
    609            }

    610        }

    611    }

    612
    613}

    614

程序名为NoteLite.exe,运行后如图:

  1. 在主编辑框中输入一些文字得:

 

 

  1. 单击统计得:

  1. 在测试编辑框中输入:桂林电子科技大学,单击插入三次得

单击删除两次得:

单击撤消两次得:

单击重做两次得

单击匹配得

 

  1. 在替换编辑框中输入:06050303,然后单击替换得

单击清空得

  1. 按退出,关闭程序.

 

 

    本次实训初始使用MFC来开发一个文章编辑器,首先去了解了相关的类,当开始发现CEditeView类建立的单文档已经实现的一个文章编辑器的大部分功能,只需要做的是重写里边的函数达到实训的目的.但由于对单文档的运用过于生疏,由于时间不允许只能换回比较上手的基于对话框的开发,也只用CEdit.先写了一个开发的计划,要实现的功能有两个亮点:1是能按列选择并删除或替换;2是能实现无限撤消和删除.最后才考虑用KMP算法实现查找匹配等功能.在开发过程中发现要实现第一点并非一件容易的事,要使用到的知识远远超出我的知识范围,只能开始第二点,首先想到的是用栈来实现,但在MFC里这也不是件容易的事,因为如何捕获文本框的即时内容变化呢?换成数组就好办多了,可以在文本框焦点得失时保存入相应的数组里,这里设两个数组,一个用于撤消,一个用于重做,最后完美的实现了第二点.在第三点中算法是没有问题,但在运行时出现一个系统的错误,这个常见的错误一般是空指针,下标越界等引起,但在调试过程中并未找到出错的下标.最后改成Brute Froce算法才得以实现删除,替换,匹配的功能.当然这个算法效率不佳,但对于这个小程序足矣.其实在实现删除,替换功能时一定要注意的一点是在文本框的内容改变时要重新获取内容才能有达到目的.这一点也是我在调试过程中发现的,很多问题总是在调试过程中得以解决.

    另外有一点我始终不明白,本想统计汉字的个数,由于用平常的方法无法实现,就想到用总字符减去空格,数字,字母,标点余下的应该就是汉字了,可以系统却把一个汉字当成了两个标点符号了,而我的标点符号集里并没有汉字.这一点会在今后的学习中多加了解,因为一个要国际化的软件总是应该要支持多国语言的.

    这次实训锻炼了我几个方面的功能:1. 规划能力;2. 自学、独立解决问题能力;3. 知识捕获、信息整理能力;4. 美工设计、排版能力;5. 综合运用知识能力

 

  1. 《数据结构习题与解答》                        (冶金工业出版社)

    《数据结构C++实现》                            (科学出版社)

    《数据结构(C++描述)》                            (清华大学出版社)

    《C语言程序设计》                            (清华大学出版社)

    《算法与数据结构—C语言描述》                (高等教育出版社)

    《算法设计与分析》                            (清华大学出版社)

    《Windows API函数实用手册》                    (冶金工业出版社)

    《MFC程序设计Using Visual C++ 6.0》            (北京希望电子出版社)

《C++.NET MFC 类库应用详解》                    (科学出版社)


评论

# re: MFC简易文章编辑器(Brute Froce算法)(符源码)  回复  更多评论   

2013-04-23 19:47 by fengjiajun
3r

只有注册用户登录后才能发表评论。


网站导航: