数据结构 括号匹配实验报告.docx
《数据结构 括号匹配实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构 括号匹配实验报告.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构括号匹配实验报告
括号的匹配
1.需求和规格说明
(1)实现括号的是否匹配的判定。
(2)实现匹配错误的提示。
(3)实现栈内容的动态显示。
2.设计
2.1.设计思想
(1)对于括号匹配的判定,首先输入字符串到缓冲区。
逐个字符读取字串,遇到的是左括号则入栈,若是右括号,则出栈。
出栈的左括号如果和右括号匹配,则一对括号匹配成功;否则,这对括号匹配失败,并给出错误提示。
(2)分析括号匹配错误出现的情况,主要有三种:
左括号数大于右括号数,左括号与右括号不匹配,右括号数大于左括号数。
根据栈的存储情况就能判定出这三种情况,并且实时的将信息放映到可视化控件上。
(3)对于匹配过程和栈内容的动态显示,可以用listbox控件实时的显示和更新。
窗口上有两个listbox控件,第一个动态显示push和pop动作以及提示错误信息;第二个listbox则动态模拟栈内的存储情况。
2.2.设计表示
(1)存储结构
Node节点
template
classNode
{
public:
elementele;
Node*pre;//前驱指针
Node*next;//后继指针
Node()
pre=NULL;
next=NULL;
}
Node(elemente)
ele=e;
Node*MakeNode(elemente)//传入参数返回一个节点指针,实现参数的封装。
Node*temp=newNode(e);
returntemp;
};
MyListStack链栈
classMyListStack
Node*base;
Node*top;
intindex;
MyListStack()//初始化链表
base=newNode();
top=base;
index=0;
voidpush(elementn)//push
Node*temp=newNode(n);
top->next=temp;
temp->pre=top;
top=temp;
index++;
voidpop(element&out)//pop
out=top->ele;
top=top->pre;
deletetop->next;
top->next=NULL;
index--;
BOOLisEmpty();//返回栈是否为空
if(index)
returnFALSE;
else
returnTRUE;
virtual~MyListStack()//析构链栈,释放空间。
Node*p=base;
Node*q=p->next;
while(p->next!
=NULL)
deletep;
p=q;
q=p->next;
(2)涉及的操作
voidCKuohaopipeiDlg:
:
OnButtonClear()//清空窗口控件。
OnButtonSlowShow(//慢速显示运行过程。
OnOK()//进行括号匹配过程。
OnSelchangeListInfo()//此函数响应列表框中光标改变的消息,定位错误的位置。
2.3.实现注释
(此部分见源代码中注释)
2.4.详细设计表示
(1)流程示意图
图表1匹配流程示意图
(2)功能示意图
图表2功能示意图
3.用户手册
(1)在编辑框中输入表达式串。
(2)点击开始匹配测试则进行快速匹配。
(3)点击慢速运行。
(4)点击错误信息,定位错误字符。
4.调试报告
输入:
{{{[1+1]+(A+d)}}}结果:
正确
{{{{}}}}))结果:
错误
}()){}}结果:
([][]))结果:
5.源代码及运行结果截图
(1)源代码
OnOK()
//TODO:
Addextravalidationhere
UpdateData(TRUE);
//MyListStackls;
m_list_info.ResetContent();//清空list
m_list_stack.ResetContent();//清空list
BOOLisNum=0;
BOOLisError=0;
intinputlength=m_cstring_input.GetLength();
if(inputlength==0)
MessageBox("输入值不能为空!
","提示");//如果字符串为空
for(intj=0;j{charstr_in=m_cstring_input.GetAt(j);if(str_in=='('||str_in=='['||str_in=='{'){isNum=1;ls.push(str_in);//若为左括号则入栈CStringtemp;temp.Format("push%cintostack\r\n",str_in);m_list_info.AddString(temp);}elseif(str_in==')'||str_in==']'||str_in=='}')//若为右括号则出栈匹配{isNum=1;charstr_out;if(!ls.isEmpty()){ls.pop(str_out);BOOLflag=0;if(str_in==')'&&str_out=='('){flag=1;}if(str_in==']'&&str_out=='['){flag=1;}if(str_in=='}'&&str_out=='{'){flag=1;}if(!flag//如果匹配不成功,则isError变量为1,并更新提示信息。{isError=1;CStringtemp;temp.Format("push%cbutcannotmatch%c<--error!",str_out,str_in);m_list_info.AddString(temp); }else//如果匹配成功,更新提示信息。{CStringtemp;temp.Format("pop%coutofstack\r\n",str_out);m_list_info.AddString(temp);}}else//如果当前栈为空,且输入为右括号时,isError为1,并更新控件信息。{isError=1;CStringtemp;temp.Format("cannotmatch%c<--error!",str_in);m_list_info.AddString(temp);}}m_list_info.RedrawWindow();UpdateData(FALSE);}if(!ls.isEmpty())//如果栈最后不为空,且栈中还有左括号,则提示栈中左括号没有匹配完成。{chartemp;ls.pop(temp);ls.push(temp);if(temp=='('||temp=='{'||temp=='['){CStringtemp;temp="stackisnotempty<--error!";m_list_info.AddString(temp);}}if(ls.isEmpty()&&isNum==1&&!isError){m_list_info.AddString("matchsuccess!");MessageBox("匹配成功!","提示");}elseif((!ls.isEmpty()&&isNum==1)||isError){m_list_info.AddString("matchfailed!");MessageBox("匹配失败!","提示");}elseif(isNum==0){MessageBox("表达式中未出现括号!","提示");}}chartemp;while(ls.index!=0){ls.pop(temp);}((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}voidCKuohaopipeiDlg::OnButtonSlowShow()//慢速显示运行过程{//TODO:Addyourcontrolnotificationhandlercodehere//TODO:Addextravalidationherem_list_info.SetRedraw();m_list_stack.SetRedraw();UpdateData(TRUE);m_list_info.ResetContent();m_list_stack.ResetContent();BOOLisNum=0;//判断是否出现括号BOOLisError=0;//判断是否出现错误intinputlength=m_cstring_input.GetLength();//获取输入字串长度if(inputlength==0){MessageBox("输入值不能为空!","提示");}else{for(intj=0;j{charstr_in=m_cstring_input.GetAt(j);if(str_in=='('||str_in=='['||str_in=='{')//如果为左括弧,则入栈。{isNum=1;ls.push(str_in);CStringtemp;temp.Format("push%cintostack\r\n",str_in);m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);temp.Format("%c",str_in);m_list_stack.AddString(temp);}elseif(str_in==')'||str_in==']'||str_in=='}')//如果为右括弧{isNum=1;charstr_out;if(!ls.isEmpty()){ls.pop(str_out);//pop括号,判断是否匹配BOOLflag=0;if(str_in==')'&&str_out=='('){flag=1;}if(str_in==']'&&str_out=='['){flag=1;}if(str_in=='}'&&str_out=='{'){flag=1;}if(!flag){isError=1;//如果不匹配,则此变量为真,便于函数末尾判断。CStringtemp;temp.Format("push%cbutcannotmatch%c<--error!",str_out,str_in);//将信息传入控件m_list_info.AddString(temp);m_list_stack.DeleteString(m_list_stack.GetCount()-1);m_list_info.SetCurSel(m_list_info.GetCount()-1);}else//如果匹配成功,将信息显示到控件。{CStringtemp;temp.Format("pop%coutofstack\r\n",str_out);m_list_info.AddString(temp);m_list_stack.DeleteString(m_list_stack.GetCount()-1);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}else{//如果栈中无括号了,且输入括号为右括号。isError=1;CStringtemp;temp.Format("cannotmatch%c<--error!",str_in);m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}m_list_info.RedrawWindow();//重画控件m_list_stack.RedrawWindow();Sleep(600);UpdateData(FALSE);}if(!ls.isEmpty())//如果栈中还有左括号,说明右括号的数量小于左括号的数量。{chartemp;ls.pop(temp);ls.push(temp);if(temp=='('||temp=='{'||temp=='['){CStringtemp;temp="stackisnotempty<--error!";//提示栈中还有未匹配的左括号。m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}if(ls.isEmpty()&&isNum==1&&!isError){m_list_info.AddString("matchsuccess!");MessageBox("匹配成功!","提示");}elseif((!ls.isEmpty()&&isNum==1)||isError){m_list_info.AddString("matchfailed!");MessageBox("匹配失败!","提示");}elseif(isNum==0){MessageBox("表达式中未出现括号!","提示");}}chartemp;while(ls.index!=0)//清空栈中的内容{ls.pop(temp);}((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}voidCKuohaopipeiDlg::OnButtonClear(){//TODO:Addyourcontrolnotificationhandlercodehere((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetWindowText("");//此函数中清空所有编辑框和listbox中的记录m_list_info.ResetContent();m_list_stack.ResetContent();m_list_info.RedrawWindow();//重画所有的控件m_list_stack.RedrawWindow();}voidCKuohaopipeiDlg::OnSelchangeListInfo()//此函数响应列表框中光标改变的消息,定位错误的位置。{//TODO:Addyourcontrolnotificationhandlercodehereinti;i=m_list_info.GetCurSel();if(i!=LB_ERR&&i{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(i,i+1);}else{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}}(2)运行截图图表3运行效果图1图表4运行效果图2
charstr_in=m_cstring_input.GetAt(j);
if(str_in=='('||str_in=='['||str_in=='{')
isNum=1;
ls.push(str_in);//若为左括号则入栈
CStringtemp;
temp.Format("push%cintostack\r\n",str_in);
m_list_info.AddString(temp);
elseif(str_in==')'||str_in==']'||str_in=='}')//若为右括号则出栈匹配
charstr_out;
if(!
ls.isEmpty())
ls.pop(str_out);
BOOLflag=0;
if(str_in==')'&&str_out=='(')
flag=1;
if(str_in==']'&&str_out=='[')
if(str_in=='}'&&str_out=='{')
flag//如果匹配不成功,则isError变量为1,并更新提示信息。
isError=1;
temp.Format("push%cbutcannotmatch%c<--error!
",str_out,str_in);
else//如果匹配成功,更新提示信息。
temp.Format("pop%coutofstack\r\n",str_out);
else//如果当前栈为空,且输入为右括号时,isError为1,并更新控件信息。
temp.Format("cannotmatch%c<--error!
",str_in);
m_list_info.RedrawWindow();
UpdateData(FALSE);
ls.isEmpty())//如果栈最后不为空,且栈中还有左括号,则提示栈中左括号没有匹配完成。
chartemp;
ls.pop(temp);
ls.push(temp);
if(temp=='('||temp=='{'||temp=='[')
temp="stackisnotempty<--error!
";
if(ls.isEmpty()&&isNum==1&&!
isError)
m_list_info.AddString("matchsuccess!
");
MessageBox("匹配成功!
","提示");
elseif((!
ls.isEmpty()&&isNum==1)||isError)
m_list_info.AddString("matchfailed!
MessageBox("匹配失败!
elseif(isNum==0)
MessageBox("表达式中未出现括号!
while(ls.index!
=0)
((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();
((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);
OnButtonSlowShow()//慢速显示运行过程
Addyourcontrolnotificationhandlercodehere
m_list_info.SetRedraw();
m_list_stack.SetRedraw();
m_list_info.ResetContent();
m_list_stack.ResetContent();
BOOLisNum=0;//判断是否出现括号
BOOLisError=0;//判断是否出现错误
intinputlength=m_cstring_input.GetLength();//获取输入字串长度
for(intj=0;j{charstr_in=m_cstring_input.GetAt(j);if(str_in=='('||str_in=='['||str_in=='{')//如果为左括弧,则入栈。{isNum=1;ls.push(str_in);CStringtemp;temp.Format("push%cintostack\r\n",str_in);m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);temp.Format("%c",str_in);m_list_stack.AddString(temp);}elseif(str_in==')'||str_in==']'||str_in=='}')//如果为右括弧{isNum=1;charstr_out;if(!ls.isEmpty()){ls.pop(str_out);//pop括号,判断是否匹配BOOLflag=0;if(str_in==')'&&str_out=='('){flag=1;}if(str_in==']'&&str_out=='['){flag=1;}if(str_in=='}'&&str_out=='{'){flag=1;}if(!flag){isError=1;//如果不匹配,则此变量为真,便于函数末尾判断。CStringtemp;temp.Format("push%cbutcannotmatch%c<--error!",str_out,str_in);//将信息传入控件m_list_info.AddString(temp);m_list_stack.DeleteString(m_list_stack.GetCount()-1);m_list_info.SetCurSel(m_list_info.GetCount()-1);}else//如果匹配成功,将信息显示到控件。{CStringtemp;temp.Format("pop%coutofstack\r\n",str_out);m_list_info.AddString(temp);m_list_stack.DeleteString(m_list_stack.GetCount()-1);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}else{//如果栈中无括号了,且输入括号为右括号。isError=1;CStringtemp;temp.Format("cannotmatch%c<--error!",str_in);m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}m_list_info.RedrawWindow();//重画控件m_list_stack.RedrawWindow();Sleep(600);UpdateData(FALSE);}if(!ls.isEmpty())//如果栈中还有左括号,说明右括号的数量小于左括号的数量。{chartemp;ls.pop(temp);ls.push(temp);if(temp=='('||temp=='{'||temp=='['){CStringtemp;temp="stackisnotempty<--error!";//提示栈中还有未匹配的左括号。m_list_info.AddString(temp);m_list_info.SetCurSel(m_list_info.GetCount()-1);}}if(ls.isEmpty()&&isNum==1&&!isError){m_list_info.AddString("matchsuccess!");MessageBox("匹配成功!","提示");}elseif((!ls.isEmpty()&&isNum==1)||isError){m_list_info.AddString("matchfailed!");MessageBox("匹配失败!","提示");}elseif(isNum==0){MessageBox("表达式中未出现括号!","提示");}}chartemp;while(ls.index!=0)//清空栈中的内容{ls.pop(temp);}((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}voidCKuohaopipeiDlg::OnButtonClear(){//TODO:Addyourcontrolnotificationhandlercodehere((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetWindowText("");//此函数中清空所有编辑框和listbox中的记录m_list_info.ResetContent();m_list_stack.ResetContent();m_list_info.RedrawWindow();//重画所有的控件m_list_stack.RedrawWindow();}voidCKuohaopipeiDlg::OnSelchangeListInfo()//此函数响应列表框中光标改变的消息,定位错误的位置。{//TODO:Addyourcontrolnotificationhandlercodehereinti;i=m_list_info.GetCurSel();if(i!=LB_ERR&&i{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(i,i+1);}else{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}}(2)运行截图图表3运行效果图1图表4运行效果图2
if(str_in=='('||str_in=='['||str_in=='{')//如果为左括弧,则入栈。
ls.push(str_in);
m_list_info.SetCurSel(m_list_info.GetCount()-1);
temp.Format("%c",str_in);
m_list_stack.AddString(temp);
elseif(str_in==')'||str_in==']'||str_in=='}')//如果为右括弧
ls.pop(str_out);//pop括号,判断是否匹配
flag)
isError=1;//如果不匹配,则此变量为真,便于函数末尾判断。
",str_out,str_in);//将信息传入控件
m_list_stack.DeleteString(m_list_stack.GetCount()-1);
else//如果匹配成功,将信息显示到控件。
//如果栈中无括号了,且输入括号为右括号。
m_list_info.RedrawWindow();//重画控件
m_list_stack.RedrawWindow();
Sleep(600);
ls.isEmpty())//如果栈中还有左括号,说明右括号的数量小于左括号的数量。
";//提示栈中还有未匹配的左括号。
=0)//清空栈中的内容
OnButtonClear()
((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetWindowText("");//此函数中清空所有编辑框和listbox中的记录
m_list_info.RedrawWindow();//重画所有的控件
inti;
i=m_list_info.GetCurSel();
if(i!
=LB_ERR&&i{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(i,i+1);}else{((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1);}}(2)运行截图图表3运行效果图1图表4运行效果图2
((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus();//定位错误
((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(i,i+1);
(2)运行截图
图表3运行效果图1
图表4运行效果图2
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1