大数据结构 括号匹配实验报告材料
括号的匹配
1.需求和规格说明
(1)实现括号的是否匹配的判定。
(2)实现匹配错误的提示。
(3)实现栈内容的动态显示。
2.设计
2.1.设计思想
(1)对于括号匹配的判定,首先输入字符串到缓冲区。逐个字符读取字串,遇到的是左括号则入栈,若是右括号,则出栈。出栈的左括号如果和右括号匹配,则一对括号匹配成功;否则,这对括号匹配失败,并给出错误提示。
(2)分析括号匹配错误出现的情况,主要有三种:左括号数大于右括号数,左括号与右括号不匹配,右括号数大于左括号数。根据栈的存储情况就能判定出这三种情况,并且实时的将信息放映到可视化控件上。
(3)对于匹配过程和栈内容的动态显示,可以用listbox控件实时的显示和更新。窗口上有两个listbox控件,第一个动态显示push和pop动作以及提示错误信息;第二个listbox则动态模拟栈内的存储情况。
2.2.设计表示
(1)存储结构
Node节点
template
class Node
{
public:
element ele;
Node *pre; //前驱指针
Node *next; //后继指针
Node()
{
pre=NULL;
next=NULL;
}
Node(element e)
{
ele=e;
pre=NULL;
next=NULL;
}
Node * MakeNode(element e)//传入参数返回一个节点指针,实现参数的封装。
{
Node
return temp;
}
};
MyListStack链栈
template
class MyListStack
{
public:
Node
Node
int index;
MyListStack() //初始化链表
{
base=new Node
top=base;
index=0;
}
void push(element n) //push
{
Node
top->next=temp;
temp->pre=top;
top=temp;
index++;
}
void pop(element & out) //pop
{
out=top->ele;
top=top->pre;
delete top->next;
top->next=NULL;
index--;
}
BOOL isEmpty(); //返回栈是否为空
{
if(index)
return FALSE;
else
return TRUE;
}
virtual ~MyListStack() //析构链栈,释放空间。
{
Node
Node
while(p->next!=NULL)
{
delete p;
p=q;
q=p->next;
}
delete p;
}
};
(2)涉及的操作
void CKuohaopipeiDlg::OnButtonClear() //清空窗口控件。
void CKuohaopipeiDlg::OnButtonSlowShow( //慢速显示运行过程。
void CKuohaopipeiDlg::OnOK() //进行括号匹配过程。
void CKuohaopipeiDlg::OnSelchangeListInfo() //此函数响应列表框中光标改变的消息,定位错误的位置。
2.3.实现注释
(此部分见源代码中注释)
2.4.详细设计表示
(1)流程示意图
图表 1 匹配流程示意图(2)功能示意图
图表 2 功能示意图
3.用户手册
(1)在编辑框中输入表达式串。
(2)点击开始匹配测试则进行快速匹配。
(3)点击慢速运行。
(4)点击错误信息,定位错误字符。
4.调试报告
输入:{{{[1+1]+(A+d)}}} 结果:正确
输入:{{{{}}}})) 结果:错误
输入:}()){}} 结果:错误
输入:([][])) 结果:错误
5.源代码及运行结果截图
(1)源代码
void CKuohaopipeiDlg::OnOK()
{
// TODO: Add extra validation here
UpdateData(TRUE);
//MyListStack
m_list_info.ResetContent(); //清空list
m_list_stack.ResetContent(); //清空list
BOOL isNum=0;
BOOL isError=0;
int inputlength=m_cstring_input.GetLength();
if (inputlength==0)
{
MessageBox("输入值不能为空!","提示"); //如果字符串为空}
else
{
for(int j=0;j { char str_in=m_cstring_input.GetAt(j); if (str_in=='('||str_in=='['||str_in=='{') { isNum=1; ls.push(str_in); //若为左括号则入栈 CString temp; temp.Format("push %c into stack \r\n",str_in); m_list_info.AddString(temp); } else if(str_in==')'||str_in==']'||str_in=='}') //若为右括号则出栈匹配 { isNum=1; char str_out; if (!ls.isEmpty()) { ls.pop(str_out); BOOL flag=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; CString temp; temp.Format("push %c but can not match %c <--error!",str_out,str_in); m_list_info.AddString(temp); } else //如果匹配成功,更新提示信息。 { CString temp; temp.Format("pop %c out of stack \r\n",str_out); m_list_info.AddString(temp); } } else //如果当前栈为空,且输入为右括号时,isError为1,并更新控件信息。 { isError=1; CString temp; temp.Format("can not match %c <--error!",str_in); m_list_info.AddString(temp); } } m_list_info.RedrawWindow(); UpdateData(FALSE); } if (!ls.isEmpty())//如果栈最后不为空,且栈中还有左括号,则提示栈中左括号没有匹配完成。 { char temp; ls.pop(temp); ls.push(temp); if (temp=='('||temp=='{'||temp=='[') { CString temp; temp="stack is not empty <--error!"; m_list_info.AddString(temp); } } if (ls.isEmpty()&&isNum==1&&!isError) { m_list_info.AddString("match success!"); MessageBox("匹配成功!","提示"); } else if ((!ls.isEmpty()&&isNum==1)||isError) { m_list_info.AddString("match failed!"); MessageBox("匹配失败!","提示"); } else if (isNum==0) { MessageBox("表达式中未出现括号!","提示"); } } char temp; while (ls.index!=0) { ls.pop(temp); } ((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus(); ((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1); } void CKuohaopipeiDlg::OnButtonSlowShow() //慢速显示运行过程 { // TODO: Add your control notification handler code here // TODO: Add extra validation here m_list_info.SetRedraw(); m_list_stack.SetRedraw(); UpdateData(TRUE); m_list_info.ResetContent(); m_list_stack.ResetContent(); BOOL isNum=0; //判断是否出现括号 BOOL isError=0; //判断是否出现错误 int inputlength=m_cstring_input.GetLength(); //获取输入字串长度if (inputlength==0) { MessageBox("输入值不能为空!","提示"); } else { for(int j=0;j { char str_in=m_cstring_input.GetAt(j); if (str_in=='('||str_in=='['||str_in=='{') //如果为左括弧,则入栈。 { isNum=1; ls.push(str_in); CString temp; temp.Format("push %c into stack \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); } else if(str_in==')'||str_in==']'||str_in=='}') //如果为右括弧 { isNum=1; char str_out; if (!ls.isEmpty()) { ls.pop(str_out); //pop括号,判断是否匹配 BOOL flag=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; //如果不匹配,则此变量为真,便于函数末尾判断。 CString temp; temp.Format("push %c but can not match %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 //如果匹配成功,将信息显示到控件。 { CString temp; temp.Format("pop %c out of stack \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; CString temp; temp.Format("can not match %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()) //如果栈中还有左括号,说明右括号的数量小于左括号的数量。{ char temp; ls.pop(temp); ls.push(temp); if (temp=='('||temp=='{'||temp=='[') { CString temp; temp="stack is not empty <--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("match success!"); MessageBox("匹配成功!","提示"); } else if ((!ls.isEmpty()&&isNum==1)||isError) { m_list_info.AddString("match failed!"); MessageBox("匹配失败!","提示"); } else if (isNum==0) { MessageBox("表达式中未出现括号!","提示"); } } char temp; while (ls.index!=0) //清空栈中的内容 { ls.pop(temp); } ((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetFocus(); ((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetSel(0,-1); } void CKuohaopipeiDlg::OnButtonClear() { // TODO: Add your control notification handler code here ((CEdit*)GetDlgItem(IDC_EDIT_INPUT))->SetWindowText(""); //此函数中清空所有编辑框和listbox中的记录 m_list_info.ResetContent(); m_list_stack.ResetContent(); m_list_info.RedrawWindow(); //重画所有的控件 m_list_stack.RedrawWindow(); } void CKuohaopipeiDlg::OnSelchangeListInfo() //此函数响应列表框中光标改变的消息,定位错误的位置。 { // TODO: Add your control notification handler code here int i; 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