您的位置:首页 > 其它

栈的应用之括号匹配

2017-11-20 14:20 218 查看
                                                                                      
栈的应用之括号匹配

首先我们来分析都有什么情况

1、右括号比左括号多          eg:(()))[b]{c}

2、左括号比右括号多          eg:(()[b]{c}

3、括号不匹配                     eg:()([)){abc}

4、括号匹配成功                 eg:(()){c}[ab]

回想一下栈的特性,后进先出。我们可以这样处理:

将所遇到的左括号入栈,如果碰到右括号,则与栈顶的元素比较。

如果碰到一个右括号且此时的栈为空,则表明右括号比左括号多。

如果碰到一个右括号,但此时与栈顶不相同,则括号不匹配。

字符全部遍历之后,如果栈不为空,则左括号多

如果栈为空,则括号匹配成功。

我们来看一下代码:

//括号匹配
#include<stack>
//判断是否为括号
bool IsBrackets(char c)
{
if (c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']')
{
return true;
}
return false;
}
bool MatchBrackets(char *str)
{
stack<char> s;
size_t len = strlen(str);

for (size_t i = 0; i < len; i++)
{
if (!IsBrackets(str[i]))
continue;
else
{
//左括号压栈
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
s.push(str[i]);
//右括号
else if (str[i] == ')' || str[i] == '}' || str[i] == ']')
{
if (s.empty())
{
cout << "右括号比左括号多" << endl;
return false;
}
else
{
if ((str[i] == ')' && s.top() == '(') || (str[i] == '}' && s.top() == '{')
|| (str[i] == ']' && s.top() == '['))
{
s.pop();
}
else
{
cout << "括号不匹配" << endl;
return false;
}
}
}
}
}
if (s.empty())
{
cout << "括号匹配" << endl;
return true;
}
else
{
cout << "左括号比右括号多" << endl;
return false;
}
}
int main()
{
char *str1 = "(()))[b]{c}";   //右比左多
char *str2 = "(()[b]{c}";    //左比右多
char *str3 = "()([)){abc}";    //不匹配
char *str4 = "(()){c}[ab]";    //匹配
char *str5 = "))((";           //不匹配
MatchBrackets(str1);
MatchBrackets(str2);
MatchBrackets(str3);
MatchBrackets(str4);
MatchBrackets(str5);

system("pause");
return 0;
}

运行结果:



看第五种特殊情况,如上若首先出现右括号,eg:"))((";这应该属于括号不匹配,可测试结果为右括号比左括号多。我们的程序还需做改进。

我们可以再添加一个栈,用来保存未能匹配的所有右括号。

在遍历结束之后,将之前的栈和此时添加的栈来进行比较,确定括号匹配问题。

代码如下:

#include<stack>
//判断是否为括号
bool IsBrackets(char c)
{
if (c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']')
{
return true;
}
return false;
}
bool MatchBrackets(char *str)
{
stack<char> s;
stack<char> right;
size_t len = strlen(str);

for (size_t i = 0; i < len; i++)
{
if (!IsBrackets(str[i]))
continue;
else
{
//左括号压栈
if (str[i] == '(' || str[i] == '{' || str[i] == '[')
s.push(str[i]);
//右括号
else if (str[i] == ')' || str[i] == '}' || str[i] == ']')
{
if (s.empty())
{
//未匹配的右括号入栈
right.push(str[i]);
//cout << "右括号比左括号多" << endl;
//return false;
}
else
{
if ((str[i] == ')' && s.top() == '(') || (str[i] == '}' && s.top() == '{')
|| (str[i] == ']' && s.top() == '['))
{
s.pop();
}
else
{
//未匹配的右括号入栈
right.push(str[i]);
//cout << "括号不匹配" << endl;
//return false;
}
}
}
}
}
if (right.empty() && s.empty())
{
cout << "括号匹配" << endl;
return true;
}
else if (right.empty() && !s.empty())
{
cout << "左括号比右括号多" << endl;
return false;
}
else if (!right.empty() && s.empty())
{
cout << "右括号比左括号多" << endl;
return false;
}
else if (!right.empty() && !s.empty())
{
cout << "不匹配" << endl;
return false;
}
}

测试:

int main()
{
char *str1 = "(()))[b]{c}";   //右比左多
char *str2 = "(()[b]{c}";    //左比右多
char *str3 = "()([)){abc}";    //不匹配
char *str4 = "(()){c}[ab]";    //匹配
char *str5 = "))((";           //不匹配
MatchBrackets(str1);
MatchBrackets(str2);
MatchBrackets(str3);
MatchBrackets(str4);
MatchBrackets(str5);

system("pause");
return 0;
}


运行结果如下,正确

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: