/********************************************************
Copyright (c) 2013, binzhouweichao@163.com
*********************************************************/
/*=================================================================
判断if语句括号是否合法
编程的时候,if条件里面的“(”、“)”括号经常出现不匹配的情况导致编译不过,请编写程序检测输入一行if语句中的圆括号是否匹配正确。同时输出语句中出现的左括号和右括号数量,如if((a==1)&&(b==1))是正确的,而if((a==1))&&(b==1))是错误的。注意if语句的最外面至少有一对括号。提示:用堆栈来做。
输入:if((a==1)&&(b==1))
输出:RIGTH 3 3
输入:if((a==1))&&(b==1))
输出:WRONG 3 4
===================================================================*/
#include <iostream> //输入输出流操作
#include <string> //string类
#define DEBUG //DEBUG模式,发布时去掉此处,就可以去掉下面相关的操作
using namespace std; //启用标准库命名空间
int main()
{
string str; //string类型变量,用于存储输入的字符串
getline(cin, str); //getline遇到回车结束,解决输入流中会出现空格的情况
size_t len = strlen(str.c_str()); //输入的字符串的长度(不包含\0)
/*
注:strlen()的返回值类型为size_t,32位下为unsigned int,64位下为long unsigned int
如果用int强制类型转换,则在len大于unsigned int的一半时,超出int的范围,导致数据不准确
只会warning,不会error
*/
//统计左右括号的数目
size_t cntL, cntR;
cntL = cntR = 0;//左右括号计数器,初始值为0,代表左右括号数为0
for(size_t i=0; i<len; i++)
{
if(str[i] == '(') //字符串的元素调用方式;字符串某元素默认为char类型
{
cntL++;
}
if(str[i] == ')')
{
cntR++;
}
}
/**************************************************************************************************
情况1:左右括号数目不等,如if(a(b),if(abc, if abc)
情况2:左右括号数均为0,如if abc
打印错误信息,退出
***************************************************************************************************/
if((cntL != cntR) || (cntL == 0))
{
cout << "WRONG" << " " << cntL << " " << cntR;
#ifdef DEBUG
system("pause");
#endif
return 0;
}
/******************************************************************************
情况3:左右括号匹配错误,如if((a)b)c(d)
情况4:最外层不是一对括号,如if(a)(b)
******************************************************************************/
size_t k = 0; //堆栈计数器,k=0表示栈空;入栈k++,出栈k--
size_t popK = 0; //出栈计数器,用于判断出栈至空时,是否右括号已经计完
/*
如果空栈情况下,还遇到出栈的情况,说明此时右括号先出现,不匹配;
如果还未到最后一个右括号,栈已空,说明不满足“最外层至少一对括号”的情况
*/
for(size_t i=0; i<len; i++)
{
if(str[i] == '(') //如果遇到左括号,入栈,即k++
{
k++;
}
if(str[i] == ')') //如果遇到右括号,出栈
{
if(k == 0) //如果出栈时,栈已空,说明右括号早于左括号出现,不匹配,打印错误信息并退出
{
cout << "WRONG" << " " << cntL << " " << cntR;
#ifdef DEBUG
system("pause");
#endif
return 0;
}
k--; //如果不符合上述情况,则出栈;不必用else。。
popK++; //出栈计数器递增
if(k == 0) //如果出栈后,导致栈空,则判断出栈计数器是否等于右括号总数
{
if(popK < cntR) //如果出栈计数器小于右括号总数,说明不满足“最外层至少一对括号”的情况,打印错误信息并退出
{
cout << "WRONG" << " " << cntL << " " << cntR;
#ifdef DEBUG
system("pause");
#endif
return 0;
}
}
}
}
//如果上述情况均没有出现,说明括号合法,打印正确信息并退出
cout << "RIGHT" << " " << cntL << " " << cntR;
#ifdef DEBUG
system("pause");
#endif
return 0;
}