用链栈实现字符串表达式括号匹配算法

字符串表达式括号匹配算法思路
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;
}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值