数据结构与算法(11)——栈习题二

题目:判定字符串中开闭分隔符是否匹配
思路:
1.分解字符串成字符数组,并创建一个栈
2.如果读取的字符不是开闭分隔符,直接忽略
  如果读取的字符是开分隔符则压栈
  如果读取的字符是闭分隔符,且栈不为空,栈顶元素出栈,否则提示匹配错误
3.如果出栈的开分隔符与读取的闭分隔符不匹配,提示匹配错误
4.字符串处理完后,如果栈不为空,则提示匹配错误
/**
 * 判定字符串中开闭分隔符是否匹配
 * @param string 需要判断的字符串
 * @return true 分隔符匹配 false 分隔符不匹配
 */
public static boolean isMatch(String string) {
    // 1.将字符串转换成字符数组
    char[] chars = string.toCharArray();
    // 2.创建一个字符栈
    LinkedListStack<Character> stack = new LinkedListStack<Character>();
    // 3.遍历字符数组
    for (int i = 0; i < chars.length; i++) {
        // 3.1 如果为开分隔符则压栈
        if ('(' == chars[i] || '{' == chars[i] || '[' == chars[i]) {
            stack.push(chars[i]);
        }
        // 3.2 如果为闭分隔符且栈不为空则出栈,否则提示匹配错误
        if (')' == chars[i] || '}' == chars[i] || ']' == chars[i]) {
            if (stack.isEmpty()) {
                System.out.println("开闭分隔符不匹配!缺少与" + chars[i] + "对应的分隔符");
                return false;
            } else {
                // 栈不为空时,判断出栈的字符是不是匹配的开分隔符
                char temp = stack.pop();
                switch (chars[i]) {
                case ']':
                    if ('[' != temp) {
                        System.out.println("开闭分隔符不匹配!缺少与" + chars[i] + "对应的分隔符");
                        return false;
                    }
                    break;
                case '}':
                    if ('{' != temp) {
                        System.out.println("开闭分隔符不匹配!缺少与" + chars[i] + "对应的分隔符");
                        return false;
                    }
                    break;
                case ')':
                    if ('(' != temp) {
                        System.out.println("开闭分隔符不匹配!缺少与" + chars[i] + "对应的分隔符");
                        return false;
                    }
                    break;
                default:
                    break;
                }
            }
        }
    }
    // 4.字符数组处理完,如果栈不为空,说明栈内有多余的开分隔符,提示匹配出错
    if (!stack.isEmpty()) {
        System.out.println("开闭分隔符不匹配!缺少与" + stack.top() + "对应的分隔符");
        return false;
    }
    return true;
} 
题目:中缀表达式转换成后缀表达式
性质:观察中缀表达式2+3*4和后缀表达式234*+
两种表达式的操作数次序相同,但操作符不同
思路:
1.栈中只存储"("和运算符
2.在遇到")"时,从栈中弹出运算符,直到"("出栈;但"("不输出
3.在比较运算符优先级时,只要栈顶运算符优先级不低于读取的运算符,就出栈
4.要保证栈最后为空
/**
 * 中缀表达式转换成后缀表达式
 * @param infix 中缀表达式
 * @return 后缀表达式
 */
public static String infixToPostfix(String infix) {

    // 1.将表达式转换成字符数组
    char[] chars = infix.toCharArray();
    // 2.后缀表达式
    StringBuffer postfix = new StringBuffer();
    // 3.创建一个字符栈,栈里面只存储"("和运算符
    LinkedListStack<Character> stack = new LinkedListStack<Character>();
    // 4.遍历字符数组
    for (int i = 0; i < chars.length; i++) {
        switch (chars[i]) {
        case '(':
        case '+':
        case '-':
        case '*':
        case '/':
            if (!stack.isEmpty() && compare(stack.top(), chars[i])) {
                postfix.append(stack.pop());
            }
            stack.push(chars[i]);
            break;
        case ')':
            while (stack.top() != '(') {
                postfix.append(stack.pop());
            }
            // 将"("弹出
            stack.pop();
            break;
        default:
            postfix.append(chars[i]);
            break;
        }
    }
    // 5.字符数组遍历完,如果栈不为空,说明栈内还有运算符
    while (!stack.isEmpty()) {
        postfix.append(stack.pop());
    }
    return postfix.toString();
}

/**
 * 运算符比较优先级
 * @param stackSymbol 栈中运算符
 * @param symbol 读取的运算符
 * @return true 栈中优先级高 false 读取的运算符优先级高
 */
public static boolean compare(char stackSymbol, char symbol) {
    int priorityOfStack = OperatorEnum.priorityOf(stackSymbol);
    int priorityOfSymbol = OperatorEnum.priorityOf(symbol);

    if ((priorityOfStack - priorityOfSymbol) >= 0) {
        // 如果读取的字符为"(",直接压入栈
        if (priorityOfSymbol == 0) {
            return false;
        }
        return true;
    }
    return false;
}
运算符以及其优先级通过枚举类型实现,如下:
public enum OperatorEnum {

    PLUS('+',1), MINUS('-',1), MULTI('*',2), DIVIDE('/',2), OPENPAREN('(',0);

    private Character operator;

    private int priority;

    private OperatorEnum(Character operator, int priority) {
        this.operator = operator;
        this.priority = priority;
    }

    /**
     * 获取运算符的对应优先级
     * @param operator 运算符
     * @return 对应的优先级
     */
    public static int priorityOf(char operator) {
        for (OperatorEnum oper : values()) {
            if (oper.getOperator() == operator) {
                return oper.getPriority();
            }
        }
        return operator;
    }

    /**
     * @return the operator
     */
    public Character getOperator() {
        return operator;
    }

    /**
     * @param operator the operator to set
     */
    public void setOperator(Character operator) {
        this.operator = operator;
    }

    /**
     * @return the priority
     */
    public int getPriority() {
        return priority;
    }

    /**
     * @param priority the priority to set
     */
    public void setPriority(int priority) {
        this.priority = priority;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值