字符串表达式括号匹配算法思路:
1、遍历字符串中的字符,遇到左括号字符先压入栈,遇到右括号,栈顶字符出栈与之进行比较,如果配对则继续循环遍历下一字符,否则就返回不匹配。例如:(6*3]
2、遍历过程中,若栈为空,但当前字符是右括号时,则返回匹配失败。例如:(7-1))
3、遍历完字符串后,若发现栈不为空,则返回不匹配。例如:(5/2
4、从第二个字符遍历开始,如果当前字符是数字,则前一个字符如果是右括号,则返回不匹配。例如:(6+)5
5、如字符串中没有括号时,返回匹配失败。例如:5+3
注意:默认不包含其他字符,例如空格,特殊字符等等。匹配成功打印yes,匹配失败打印no。测试内存泄漏,windows安装visual leak detect,linux安装valgrind。
gcc编译:
g++ -g -o .test_str_bracket_match test_str_bracket_match.cpp -std=c++11
检测内存问题:
valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./test_str_bracket_match
link_stack.h
#ifndef __LINK_STACK_H_2020_11_25__
#define __LINK_STACK_H_2020_11_25__
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
template<typename T>
class LinkStack {
public:
typedef struct Node {
T data;
struct Node* next;
}Node;
LinkStack():size_(0), head_(nullptr) {
_Init();
}
void Push(T val) {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return;
}
Node* new_node = new (nothrow) Node;
if (nullptr == new_node) exit(1);
new_node->data = val;
new_node->next = head_->next;
head_->next = new_node;
++size_;
}
void Pop() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return;
}
if (0 == size_) {
cout << "current stack is empty" << endl;
return;
}
Node* first_node = head_->next;
if (nullptr == first_node) {
cout << "data is error" << endl;
return;
}
head_->next = first_node->next;
delete first_node;
first_node = nullptr;
--size_;
}
T Top() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return T();
}
if (Empty()) {
cout << "stack is empty" << endl;
return T();
}
else {
return head_->next->data;
}
}
bool Empty() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return false;
}
return 0 == size_ || nullptr == head_->next;
}
size_t Size() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return 0;
}
return size_;
}
Node* At() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return nullptr;
}
return head_->next;
}
void Clear() {
_UnInit();
}
~LinkStack() {
_UnInit();
delete head_;
head_ = nullptr;
size_ = 0;
}
protected:
void _Init() {
if (nullptr != head_) {
cout << "stack has init" << endl;
return;
}
head_ = new (nothrow) Node;
if (nullptr == head_) exit(1);
memset(head_, 0, sizeof(Node));
}
void _UnInit() {
if (nullptr == head_) {
cout << "stack is not init" << endl;
return;
}
if (0 < size_) {
Node* p = head_->next;
Node* q = p;
while (p) {
q = p->next;
delete p;
--size_;
p = q;
}
if (0 != size_) {
cout << "data is error" << endl;
size_ = 0;
}
head_->next = nullptr;
}
}
private:
size_t size_;
Node* head_;
};
template<typename T>
void Show(LinkStack<T>& sta) {
if (sta.Empty()) {
cout << "stack is empty" << endl;
return;
}
typedef typename LinkStack<T>::Node Node;
Node* p = sta.At();
while (nullptr != p) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
#endif // LinkStack
test_link_stack.cpp
#include "link_stack.h"
#ifdef _WIN32
#include "vld.h"
#endif
int main() {
LinkStack<int> sta;
cout << "sta size = " << sta.Size() << endl;
Show(sta);
sta.Push(1);
sta.Push(2);
sta.Push(3);
cout << "sta size = " << sta.Size() << endl;
Show(sta);
cout << "sta top = " << sta.Top() << endl;
sta.Pop();
sta.Pop();
cout << "sta size = " << sta.Size() << endl;
Show(sta);
sta.Clear();
cout << "sta size = " << sta.Size() << endl;
Show(sta);
for (int i = 5; i < 8; ++i) {
sta.Push(i);
}
Show(sta);
return 0;
}
test_str_bracket_match.cpp
#include "link_stack.h"
#include <iostream>
#include <string>
using namespace std;
bool IsMatch(const string& str, LinkStack<char>& sta) {
bool has_bracket = false;
for (size_t i = 0; i < str.size(); ++i) {
char cur_char = str[i];
if (0 != i) {
if ('0' <= cur_char && '9' >= cur_char) {
char prev_char = str[i - 1];
if (')' == prev_char || ']' == prev_char || '}' == prev_char) {
return false;
}
}
}
if ('(' == cur_char || '[' == cur_char || '{' == cur_char) {
has_bracket = true;
sta.Push(cur_char);
}
else {
if (sta.Empty()) {
if (')' == cur_char || ']' == cur_char || '}' == cur_char) {
return false;
}
}
else {
char top_char = sta.Top();
if (('(' == top_char && ')' == cur_char) || ('[' == top_char && ']' == cur_char) || ('{' == top_char && '}' == cur_char)) {
sta.Pop();
}
}
}
}
if (!sta.Empty() || !has_bracket) {
return false;
}
return true;
}
int main() {
// string str = "(6*3]";
// string str = "(7-1))";
// string str = "(5/2";
// string str = "(6+)5";
// string str = "5+3";
string str = "{(1+2)+[(1+2)*(2-1)]}";
LinkStack<char> sta;
bool res = IsMatch(str, sta);
if (res) {
cout << "Yes" << endl;
}
else {
cout << "No" << endl;
}
return 0;
}