標籤:exce 開始 轉換 調試 code 中括弧 view 堆棧 log
最近碰到兩個演算法題,覺得比較有代表性,特記錄分享如下:
題1: 給定一個整形數字,求一串數字,這串數字需要滿足相加等於這個給定的數字,且這串數字必須順序排列。
題2: 有一個字串,判斷字串內的括弧(大括弧,小括弧,中括弧,角括弧等等)是全閉合的,也就是說一個正括弧後必須是相同括弧類型的反括弧,比如{{[]}}是合法的,({])是非法,括弧中可夾雜數字,字母。
開始拿到第一個題目,首先就想到了和冒泡演算法有點類似,原理又有些不同。
第一個和後面數字依次相加,直到和等於給定數字就把所有加數轉成字串輸出,然後第二個數和後面數字依次相加直到和等於給定數字就把所有加數轉成字串輸出,
如此迴圈直到第一個加數大於等於給定數字。
下面是具體實現代碼:
1. 根據參數a初始化一個長度為a的數組,數組從1開始。
2. 取第一個數和後面數相加,如何和等於a則將加數存放在list容器。
public List<String> a (int a) { int[] arr=new int[a]; for (int i=0; i<a;i++){ arr[i]=i+1; } List<String> strList = new ArrayList<String>(); for (int i = 1; i < arr.length; i++) { int sum = i; String str = i + ","; for (int j = i+1; j < arr.length; j++) { sum += j; str += j + ","; if (sum == a) { strList.add(str); } } } return strList; }
第二個題目剛開始拿到時不知道如何處理,首先想到的是建立三個list容器來存放三種括弧,然後將字串轉換成char一個個遍曆,如果碰到正括弧就直接存入容器,碰到反括弧就去容器驗證最後一個是不是正括弧,乍一看感覺沒問題於是開始寫代碼。
寫著寫著發現哪裡不對勁,仔細一想這種方法不能識別各種括弧的位置關係,只能判斷正括弧和反括弧是不是成對出現,比如[(])這種會被程式識別為合法,其實這種是非法的。
於是,冷靜下來重新思考,突然靈光一現,可以利用堆棧類來處理啊,碰到正括弧就壓入棧頂,碰到反括弧就判斷棧頂是不是相同類型的正括弧,是就移除棧頂元素,最後判斷棧是否為空白,為空白則返貨valid,否則返回invalid。
於是開始寫代碼,調試,結果卻悲劇了,提示錯誤,重新review代碼,無果。查看錯誤資訊peek是unknown source,初步判斷是堆棧類哪個地方出問題了。
public void check1(String s) { Stack<Character> sc=new Stack<Character>(); char[] c=s.toCharArray(); for (int i = 0; i < c.length; i++) { if (c[i]==‘(‘||c[i]==‘[‘||c[i]==‘{‘) { sc.push(c[i]); } else if (c[i]==‘)‘) { if (sc.peek()==‘(‘) { sc.pop(); } }else if (c[i]==‘]‘) { if (sc.peek()==‘[‘) { sc.pop(); } }else if (c[i]==‘}‘) { if (sc.peek()==‘{‘) { sc.pop(); } } } if (sc.empty()) { System.out.println("valid"); }else { System.out.println("not valid"); } }
Exception in thread "main" java.util.EmptyStackException at java.util.Stack.peek(Unknown Source) at Sum.check1(Sum.java:68) at Sum.main(Sum.java:91)
苦思不得解,於是上網查資料發現是由於堆棧是空導致peek報錯。重新review代碼,發現是由於遇到反括弧時堆棧為空白,而此時代碼執行peek導致出錯。
找到問題原因就好辦了,馬上在遇到反括弧時檢查堆棧是否為空白,為空白則將反括弧壓入堆棧然後退出迴圈,否則執行peek。
重新運行代碼,問題成功修複!
public void check(String s) { Stack<Character> sc=new Stack<Character>(); char[] c=s.toCharArray(); for (int i = 0; i < c.length; i++) { if (c[i]==‘(‘||c[i]==‘[‘||c[i]==‘{‘) { sc.push(c[i]); } else if (c[i]==‘)‘) { if (sc.empty()) {sc.push(c[i]); continue;} else if (sc.peek()==‘(‘) { sc.pop(); } }else if (c[i]==‘]‘) { if (sc.empty()) {sc.push(c[i]); continue;} else if (sc.peek()==‘[‘) { sc.pop(); } }else if (c[i]==‘}‘) { if (sc.empty()) {sc.push(c[i]); continue;} else if (sc.peek()==‘{‘) { sc.pop(); } } } if (sc.empty()) { System.out.println("String \""+s+"\" is valid");// System.out.println(sc.size()); }else { System.out.println("String \""+s+"\" is not valid");// System.out.println(sc.size()); } }
測試和結果:
public static void main(String[] args){ Sum test = new Sum(); //當第一個字元就是反括弧: test.check(")"); test.check("]"); test.check("}"); test.check("[]"); test.check("[a(d(dwe)we)we{we[wew]we}we]"); test.check1("(s[d]s{d}sss)"); System.out.println(test.a(15)); System.out.println(test.a(5000)); }
String ")" is not validString "]" is not validString "}" is not validString "[]" is validString "[a(d(dwe)we)we{we[wew]we}we]" is validvalid[1,2,3,4,5,, 4,5,6,, 7,8,][23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,, 188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,, 305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,, 998,999,1000,1001,1002,]
演算法 - 堆棧類和嵌套迴圈執行個體運用