1. 程式人生 > >堆疊應用——括號匹配問題

堆疊應用——括號匹配問題

假設一個算術表示式中包含圓括號()、方括號[]和花括號{}三類括號,要求判斷表示式中括號是否正確匹配配對。

分析:括號匹配符號後到的括號要最先被匹配,所以滿足棧“後進先出”的特點。

括號匹配共有四種情況:(1)左右括號配對次序不正確,即存在類似“(]”這種情況;(2)右括號多於左括號;(3)左括號多於右括號;(4)匹配正確。

綜上:我們可以儲存表示式的字串並按順序掃描,進行匹配。順序棧和鏈式堆疊都可以;

下面看程式碼:(不再構造棧類,上篇有)

package StackAndQueue;
/**
* @author sun
* 建立時間:2017年3月30日下午2:52:31
*/
public class BraceMatch {
	//遍歷字元陣列並利用進棧出棧匹配括號
	static void expIsCorrect(String[] exp,int n)throws Exception{
		SeqStack myStack = new SeqStack();
		//LinStack myStack = new LinStack(); //也可以用鏈式堆疊
		for(int i=0;i<n;i++){//如果是左括號就入棧
			if((exp[i].equals(new String("(")))
					|| (exp[i].equals(new String("[")))
					|| (exp[i].equals(new String("{"))))
				myStack.push(exp[i]);
			//如果是右括號)並且和棧頂(匹配,出棧
			else if((exp[i].equals(new String(")"))) && myStack.notEmpty()
					&& myStack.getTop().equals(new String("(")))
				myStack.pop();
			//遍歷的右括號)和棧頂不匹配,說明公式錯誤,結束遍歷
			else if((exp[i].equals(new String(")"))) && myStack.notEmpty()
					&& !myStack.getTop().equals(new String("("))){
				System.out.println("左右括號匹配次序不正確!");
				return;
			}
			//如果是右括號]並且和棧頂[匹配,出棧
			else if((exp[i].equals(new String("]"))) && myStack.notEmpty()
					&& myStack.getTop().equals(new String("[")))
				myStack.pop();
			//遍歷的右括號]和棧頂不匹配,說明公式錯誤,結束遍歷
			else if((exp[i].equals(new String("]"))) && myStack.notEmpty()
					&& !myStack.getTop().equals(new String("["))){
				System.out.println("左右括號匹配次序不正確!");
				return;
			}
			//如果是右括號}並且和棧頂{匹配,出棧
			else if((exp[i].equals(new String("}"))) && myStack.notEmpty()
					&& myStack.getTop().equals(new String("{")))
				myStack.pop();
			//遍歷的右括號}和棧頂不匹配,說明公式錯誤,結束遍歷
			else if((exp[i].equals(new String("}"))) && myStack.notEmpty()
					&& !myStack.getTop().equals(new String("{"))){
				System.out.println("左右括號匹配次序不正確!");
				return;
			}
			//如果棧已空,但還存在右括號,說明右括號多了
			else if((exp[i].equals(new String(")")))
					|| (exp[i].equals(new String("]")))
					|| (exp[i].equals(new String("}")))
					&& !myStack.notEmpty()){
				System.out.println("右括號多餘左括號!");
				return;
			}
		}
		//遍歷完成後棧內還有元素,說明左括號多了
		if(myStack.notEmpty())
			System.out.println("左括號多餘右括號!");
		else
			System.out.println("括號匹配正確!");
	}
	
	private static String[] strToString(String str){//把字串轉換為String型別陣列
		//為什麼不轉換為字元陣列char[]呢?
		//因為只有String型別的資料才具有可比性,也就是能用equals
		int n = str.length();
		String[] a = new String[n];
		for(int i=0;i<n;i++){
			a[i] = str.substring(i,i+1);//取子串含頭不含尾,故可以取出i位置的字元並返回字串型別
		}
		return a;
	}
	
	public static void main(String[] args) {
		String str;
		int n;
		try{
			str = "(())abc{[}(){";//左右括號匹配次序不正確
			n = str.length();
			String[] a = strToString(str);
			expIsCorrect(a,n);
			
			str = "(()))abc{[]}";//右括號多餘左括號
			n = str.length();
			String[] b = strToString(str);
			expIsCorrect(b,n);
			
			str = "(()()abc{[]}";//左括號多餘右括號
			n = str.length();
			String[] c = strToString(str);
			expIsCorrect(c,n);
			
			str = "(())abc{[]}";//括號匹配正確!
			n = str.length();
			String[] d = strToString(str);
			expIsCorrect(d,n);
		}
		catch(Exception e){
			System.out.println(e.getMessage());
		}

	}
}
/*
左右括號匹配次序不正確!
右括號多餘左括號!
左括號多餘右括號!
括號匹配正確!
 */