一种用Java解决括号匹配问题的方案:

一种用Java解决括号匹配问题的方案:

题目:描述:给定一串由(、)、[、]、{、}组成的括号序列,输出最长的合法括号序列长度。合法括号序列定义如下:

  1. 空括号序列是合法的
  2. 若括号序列A合法,则(A)、[A]、{A}也是合法的
  3. 若括号序列A和B均合法,则AB也是合法的

输入:括号序列

输出:最长合法序列长度

样例1
输入:{}(((}}})))[[[]])
输出: 4

代码:


package FileIO;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Stack;

public class ParenthesisMatch {
    public static void main(String[] args) {
        /*
        //输入括号序列String
        System.out.println("请输入一个括号序列:");
        String parenthesisStr = new Scanner(System.in).next();
        */
        String parenthesisStrTest="{}(((}}})))[[[]])";
        //首先判断序列是否包含括号以外的非法字符
        for (int i = 0; i <parenthesisStrTest.length() ; i++) {
            char c=parenthesisStrTest.charAt(i);
            if(c!='{' && c!='(' &&c!='[' &&c!=']' &&c!=')' &&c!='}' ){
                System.out.println("序列包含括号以外的非法字符,请检查");
                System.exit(0);
            }
        }
        //创建栈对象用来存储括号
        Stack<Character>  stack=new Stack<>();

        //记录一共出栈的次数,测试用
        int popCount=0;
        //元素入栈就往bigPopCount中加0,出栈就往bigPopCount加1,出栈都是左右括号两次连续出栈,故1的数目为偶数
        ArrayList<Integer> bigPopCount=new ArrayList<>();

        for (int i = 0; i < parenthesisStrTest.length();) {
            // 判断栈中是否有>=2个元素,有则isTwoPiPei,无则i++,等待下一元素进栈
            stack.push(parenthesisStrTest.charAt(i));
            if(stack.size() < 2) {
                //将chars[i]装入栈stack
                i++;
                //元素入栈就往bigPopCount中加0
                bigPopCount.add(0);
            }else {
                //中间变量mediatechar接收栈顶元素
                char mediatechar=stack.pop();
                if (isTwoPiPei(stack.peek(),mediatechar)) {//比较栈顶-1元素与栈顶元素是否匹配,但不能破坏栈
                    /*
                    //栈顶元素删除了,应该重新入栈
                    stack.push(mediatechar);
                    peak元素入栈后出栈,这两句话抵消了
                    stack.pop();
                    */
                    popCount++;
                    //出栈就往bigPopCount加1
                    bigPopCount.add(1);

                    stack.pop();
                    popCount++;
                    //System.out.println("执行了匹配后出栈");
                    //出栈就往bigPopCount加1
                    bigPopCount.add(1);

                }else {
                    //栈顶元素删除了,为了不破坏栈,应该重新入栈
                    stack.push(mediatechar);
                    //元素入栈就往bigPopCount中加0
                    bigPopCount.add(0);
                }
                i++;
            }
        }

        System.out.println("全部括号序列是否合法:"+stack.isEmpty());
        System.out.println(("一共有合法序列长度:"+popCount));
        System.out.println("bigPopCount:"+ bigPopCount);
        //对bigPopCount中连续的1求区段和
        ArrayList<Integer> bigPopCountSectionSum=new ArrayList<>();
        int sum=0;
        for (int i = 0; i < bigPopCount.size()-1; i++) {//一次读取两个
            int singleleft=bigPopCount.get(i);
            int singleright=bigPopCount.get(i+1);

            if(singleleft == 0 && singleright==1){
               //开始计数
                sum++;
            }
            if(singleleft == 1 && singleright==1){
                //继续计数
                sum++;
            }
            if((singleleft == 1 && singleright==0 )||(singleleft == 1 && singleright==1 && i==bigPopCount.size()-2)){
                //结束计数,上传连续1的区域和
                bigPopCountSectionSum.add(sum);
                //sum清零
                sum=0;
            }
        }
        System.out.println("bigPopCountSectionSum:"+bigPopCountSectionSum);

        //获取bigPopCountSectionSum中最大值的返回
        int max=0;
        for (int element:bigPopCountSectionSum) {
         if(element>max){
             max=element;
         }
        }

        System.out.println("最长合法序列长度:"+max);

    }


    //判断a,b是否是一对括号,a左b右返回true
    public static boolean isTwoPiPei(char a,char b){
        if(a == '{' && b== '}'){
            return  true;
        }
        if(a == '(' && b== ')'){
            return  true;
        }
        if(a == '[' && b== ']'){
            return  true;
        }
        return false;
    }


}


```java


由于我也是初学者,并没有考虑更简单的算法,希望各位多多包涵。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值