/********************************************************
Copyright (c) 2013, [email protected]
*********************************************************/
/*=================================================================
判斷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;
}