Stack声明见前文:https://blog.csdn.net/hanzheng6602/article/details/80053607
括号匹配
匹配串类似 “(()()abc{[]})”
思路:一个指针遍历串,如是左括号入栈,右括号则出栈并于当前指针比较是否匹配。再指针指向\0,并且栈为空时才是匹配模式
//匹配成功返回1
int match_brackets(const char * string)
{
if (NULL == string) {
return 1;
}
Stack s;
init(&s);
//考虑左括号多,右括号多,和括号类型顺序不同三种情况
while (*string) {
if (*string == '(' || *string == '[' || *string == '{') {
pushBack(&s, *string);
string++;
continue;
}
else if (*string == ')' || *string == '}' || *string == ']') {
char tmp = top(&s);
pop(&s);
if ((*string == ')'&& tmp == '(') ||
(*string == '}'&& tmp == '{') ||
(*string == ']'&& tmp == '[') ) {
string++;
continue;
}
else {
//顺序不匹配
return 0;
}
}
else {
string++;
}
}
//只有当字符串扫描完了,并且栈中括号都匹配完了,才是正确匹配
if (isEmpty(&s)) {
return 1;
}
return 0;
}
逆波兰表达式
操作数放前,操作符置后
例如 ” 12 3 4 + * 6 - 8 2 / +” = 12*(3+4)- 6 + 8/2
思路:指针遍历串,如果是数字则入栈,操作符则取出两个栈元素运算,然后入栈,指针指向空时返回栈顶值。
//错误串返回-1,其他返回表达式值
int exp(const char* str)
{
if(NULL == str){
return 0;
}
char *low = str;
char *fast = str;
Stack s;
init(&s);
//排除掉串前多个空格
while (*low && *low == ' ') {
low++;
}
fast = low;
//开始处理
while (*fast) {
if (isdigit(*low)) {
//读取一个数字
int sum = 0;
while (*fast && isdigit(*fast)) {
sum = sum * 10 + (*fast - '0');
fast++;
}
pushBack(&s, sum);
}
else if(*low=='+' || *low == '-' || *low == '*' || *low == '/'){
//是操作符
int tmp = 0;
switch (*low) {
case '+':
tmp = top(&s); pop(&s);
tmp += top(&s); pop(&s);
pushBack(&s, tmp);
break;
case '-':
tmp = top(&s); pop(&s);
tmp = top(&s) - tmp; pop(&s);
pushBack(&s, tmp);
break;
case '*':
tmp = top(&s); pop(&s);
tmp *= top(&s); pop(&s);
pushBack(&s, tmp);
break;
case '/':
tmp = top(&s); pop(&s);
tmp = top(&s) / tmp; pop(&s);
pushBack(&s, tmp);
break;
default:break;
}
fast++;
}
else {
return -1;
}
//low和fast指向下一个字符开头
while (*fast && *fast == ' ') {
fast++;
}
low = fast;
}
return top(&s);
}