数据结构与算法之利用栈先入后出解决括号匹配问题

数据结构与算法之利用栈先入后出解决括号匹配问题

1.括号匹配问题:给定一个字符串,里边包含{,[,(,},],)等字符,请使用一种实现括号匹配检测功能?

2.观察思路:如给定字符串{【()】},拿到字符串后我们可能需要对字符串进行观察,发现可以将字符串中每个字符括号按照开口方向进行分类,向左开口的总需要一个向右开口的进行匹配,想到可以将这个字符串拆成单个字符,用数组存储,然后自定义数据字典,将匹配的字符串分装起来,利用栈将向右开口的字符逐个压入栈顶,遇到第一个向左开口的字符就将其下标记录下来,然后逐个出栈匹配,如果最终栈为空说明所有括号都匹配成功,此问题解决

3.栈此处使用数组实现,代码待完善,出栈后缩容逻辑待实现,以下是代码:

stack接口定义数据结构的常用操作:

public interface Stack<E> {

	void push(E e);
	
	E pop();
	
	int size();
	
	boolean isEmpty();
} 

arraystack 栈接口stack的实现类

public class ArrayStack<E> implements Stack<E>{

    E container[] = null;
    int size;
    int maxSize = 1<<1000;
    int defaultSize = 1<<3;
    public ArrayStack() {
        container = (E[]) new Object[defaultSize];
    }
    public ArrayStack(Integer initCap) {
        super();
        if(initCap>maxSize)
            throw new RuntimeException("数组定义超过栈的最大限制");
        else if(Optional.of(initCap).isPresent())
            container = (E[]) new Object[initCap];
    }

    @Override
    public void push(E e) {
        judgeSize(1);
        container[size++] = e;
    }

    /**
     * mode(grow1,decrese-1)
     * @param mode
     */
    private void judgeSize(int mode) {
        if(size>=container.length&&mode==1) {
            resize(container.length<<1);
        }else if(mode==-1&&size>0&&size <= container.length>>1) {
            resize(container.length>>1);
        }
    }
    private void resize(int cap) {
        if(cap>maxSize)
            throw new RuntimeException("数组定义超过栈的最大限制");
        E temp[] = (E[]) new Object[cap];
        int current = size>cap?cap:container.length;
        for(int i=0;i<current;i++) {
            temp[i] = container[i];
        }
        container = temp;
    }
    @Override
    public E pop() {
        E e = container[--size];
        container[size] = null;
        //judgeSize(-1);
        return e;
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

}

该问题解决代码实现:

Map<String, String> dict = new HashMap<String, String>();
        dict.put("{", "}");
        dict.put("[", "]");
        dict.put("(", ")");
        dict.put("(", ")");
        dict.put("【", "】");
        Stack<String> stack = new ArrayStack<String>();
        while(true) {
            String str = new Scanner(System.in).nextLine();
            int first = 0;
            for(int i=0;i<str.length();i++) {
                String c = str.charAt(i)+"";
                if(dict.keySet().contains(c))
                    stack.push(c);
                else {
                    first = i;
                    break;
                }
            }
            for(int i=first;i<str.length();i++) {
                String c = str.charAt(i)+"";
                if(dict.get(stack.pop()).equals(c))
                    continue;
                else {
                    break;
                }
            }
            System.out.println("匹配成功:"+stack.isEmpty());
        }

 问题二.模拟浏览器前进后退功能

 

public class StackTest {

    public static void main(String[] args) {
//        Stack<Integer> stack = new ArrayStack<Integer>();
//        for(int i=0;i<100;i++) {
//            stack.push(i);
//        }
//        for(int i=0;i<100;i++) {
//            System.out.println(stack.pop());
//        }
//        kuohaojiance();
        browerforwardandback();
    }
    
    private static void kuohaojiance() {
        Map<String, String> dict = new HashMap<String, String>();
        dict.put("{", "}");
        dict.put("[", "]");
        dict.put("(", ")");
        dict.put("(", ")");
        dict.put("【", "】");
        Stack<String> stack = new ArrayStack<String>();
        while(true) {
            String str = new Scanner(System.in).nextLine();
            int first = 0;
            for(int i=0;i<str.length();i++) {
                String c = str.charAt(i)+"";
                if(dict.keySet().contains(c))
                    stack.push(c);
                else {
                    first = i;
                    break;
                }
            }
            for(int i=first;i<str.length();i++) {
                String c = str.charAt(i)+"";
                if(dict.get(stack.pop()).equals(c))
                    continue;
                else {
                    break;
                }
            }
            System.out.println("匹配成功:"+stack.isEmpty());
        }
    }
    
    static class page{
        String pageName;
        int depth;
        
        public page(String pageName, int depth) {
            super();
            this.pageName = pageName;
            this.depth = depth;
        }
        public String getPageName() {
            return pageName;
        }
        public void setPageName(String pageName) {
            this.pageName = pageName;
        }
        public int getDepth() {
            return depth;
        }
        public void setDepth(int depth) {
            this.depth = depth;
        }
        @Override
        public String toString() {
            return "page [pageName=" + pageName + ", depth=" + depth + "]";
        }
        
    }
    public static void browerforwardandback() {
        Stack<page> pagecached = new ArrayStack<page>();
        Stack<page> back = new ArrayStack<page>();
        //模拟点击页面操作,逐层进入
        for(int i=0;i<4;i++) {
            pagecached.push(new StackTest.page((char)(65+i)+"", i));
        }
        pagecached.print();
        //模拟后退操作
        System.out.println("后退操作2步");
        back.push(pagecached.pop());
        back.push(pagecached.pop());
        pagecached.print();
        
        //模拟后退操作
        System.out.println("前进操作1步");
        pagecached.push(back.pop());
        pagecached.print();
        
        System.out.println("在c页面进入M页面");
        pagecached.push(new StackTest.page("M", pagecached.get().depth+1));
        pagecached.print();
        System.out.println("后退操作1步");
        back.push(pagecached.pop());
        pagecached.print();
    }
}

模拟输出:

数据结构与算法之利用栈先入后出解决括号匹配问题

 问题三:模拟加减乘除操作:

思路:创建两个栈,第一个栈A用来存放数字,第二个栈B用来存放操作符号,程序开始从左到右依次遍历字符,遇到数字就放入栈A,遇到符号时如果B栈栈顶无符号就入栈,如果有则比较待入栈符号与栈顶符号优先级,如果当前符号优先级比栈顶元素优先级高或相同,则直接从栈A中出栈两个数做该操作后将操作结果压入A栈顶,继续往后遍历,直到计算到最终结果