栈应用——括号匹配和逆波兰表达式

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);
}

猜你喜欢

转载自blog.csdn.net/hanzheng6602/article/details/80077502