Tại sao việc thay đổi thứ tự biểu thức trong câu lệnh if dẫn đến lỗi?

# include <iostream>
# include <stack>
# include <string>
# include <cstdlib>
int priority(char);
int priority(char c)
{
	if(c == '*'|| c == '/') return 2;
	if(c == '+'|| c == '-') return 1;
	if(c == '(')			return 0;
}
using namespace std;
int main()
{
	stack <char> stack;
	string infix = "(2*3+7/8)*(5-1)";
	char temp;
	for(int i = 0; i < infix.length(); i++)
	{
		switch(infix[i])
		{
			case '('	:stack.push(infix[i]);break;
			case ')'	:	do
							{
								temp = stack.top();
								stack.pop();
								if(temp != '(') cout << temp;
							}
							while(temp != '(');break;
			case '*'	:	if((!stack.empty()) && priority(infix[i]) <= priority(stack.top())) {cout << stack.top();stack.pop();}
							stack.push(infix[i]);break;
			case '/'	:	if((!stack.empty()) && priority(infix[i]) <= priority(stack.top())) {cout << stack.top();stack.pop();}
							stack.push(infix[i]);break;
			case '+'	:	if((!stack.empty()) && priority(infix[i]) <= priority(stack.top())) {cout << stack.top();stack.pop();}
							stack.push(infix[i]);break;
			case '-'	:	if((!stack.empty()) && priority(infix[i]) <= priority(stack.top())) {cout << stack.top();stack.pop();}
							stack.push(infix[i]);break;
			default 	:	cout << infix[i];break;
		}
	}
	while(!stack.empty()) 
	{
		cout << stack.top();
		stack.pop();
	}



	system("pause");
	return 0;
}

Khi em đổi if((!stack.empty()) && priority(infix[i]) <= priority(stack.top())) thành if(priority(infix[i]) <= priority(stack.top()) && !stack.empty()) lại bị lỗi

PLZ, đừng đặt tên biến là stack, vì stack là 1 kiểu dữ liệu trong STL C++.

if((!stack.empty()) && priority(infix[i]) <= priority(stack.top()))

Đầu tiên, ta kiểm tra stack có rỗng hay không, nếu không rỗng thì kiểm tra mệnh đề tiếp theo. Stack không rỗng thì mới có top của stack được

if(priority(infix[i]) <= priority(stack.top()) && !stack.empty())

Bạn đâu thể chắc chắn được rằng stack còn có phần tử nào không để mà lấy top. Nếu stack rỗng, code dính lỗi ngay lập tức.

Ý nghĩa của việc kiểm tra !stack.empty() là để tránh tình trạng truy cập vào top của stack bị lỗi (do stack rỗng). Do vậy, ta phải đặt nó ở đầu câu lệnh if.

5 Likes

Dạ em cám ơn rất nhiều ạ. Em hiểu rồi ạ.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?