括號匹配
檢測括號匹配是比較常見的功能需求,比如編寫代碼時,往往因爲多了一個括號(當然少了也不行),編程工具,例如vs,會提示大批量的錯誤,這時我們往往找到對應缺失的括號添加或去除就可以了。利用棧就可以很高效的實現這一功能。我們僅就圓括號、方括號、花括號的檢測爲例進行簡要的闡述。
算法原理闡述
做一個空棧。讀入字符知道字符串尾部。如果字符是一個開放字符(“(”、“[”、“{”),入棧;如果字符是一個封閉字符(“)”、“]”、“}”),若棧爲空,則報錯,若棧非空,則判斷棧頂的開放字符是否和該封閉字符對應,若對應,則彈出棧頂元素,若不對應,則報錯。字符串處理完畢後檢測棧的情況,若非空則報錯。
下面依照算法原理的闡述,編寫代碼。
#include <iostream>
#include <stack>
#include <string>
using namespace std;
bool paren(const string expression) {
stack<char> s;
for (int i = 0; i < expression.length(); i++) {
if (expression.at(i) == '(' ||
expression.at(i) == '{' ||
expression.at(i) == '[') {
s.push(expression.at(i));
}
else if (expression.at(i) == ')' ||
expression.at(i) == '}' ||
expression.at(i) == ']') {
if (s.empty()) {
return false;
}
else{
switch (expression.at(i))
{
case ')':
if (s.top() != '(') {
return false;
}
else{
s.pop();
break;
}
case '}':
if (s.top() != '{') {
return false;
}
else{
s.pop();
break;
}
case ']':
if (s.top() != '[') {
return false;
}
else{
s.pop();
break;
}
default:
return false;
}
}
}
}
return s.empty();
}
代碼測試。
int main(int argc, char* argv[])
{
cout << "input expression" << endl;
//string line;
//cin >> line;
string line;
getline(cin, line);
if (paren(line)) {
cout << "parens in expression are matched..." << endl;
}
else {
cout << "parens in expression are not matched..." << endl;
}
system("pause");
return 0;
}
關於測試代碼,字符串的讀入有很多方式,
string line;
cin >> line;
這種方式無法讀入帶空格的字符串;
string line;
getline(cin, line);
這種方式可以讀取一行,以回車符爲結束符;
當然還有很多方式,比如讀段落等,有人這樣實現,
string s;
int n;
cin>>n;
cin.ignore();
for(int i=0;i<n;i++)
{
getline(cin,s);
cout<<s<<endl;
}
但是需要確定n的大小,固定了行數,這不是我們期望的。
方式有很多,小夥伴可以根據自己需要進行編寫,當然這不屬於本文的討論內容,有興趣的小夥伴可以自己多研究研究。下面看一下結果。