1. 程式人生 > >棧的應用—分隔符匹配

棧的應用—分隔符匹配

tr1 匹配 line other nextline author targe mat bool

例二、分隔符匹配問題

1、問題描述

編譯器在編譯一段代碼時,首先進行的就是分隔符的匹配,常見的分隔符有{ } [ ] ( )/* */

2、思路

首先要知道的一件事就是:分隔符運行嵌套,而且,讀入的順序和處理的順序相反,很顯然是用棧。 算法描述如下: 從左到右掃描java語句,從語句中不斷的讀取字符,每次讀取一個字符,若發現它是左分割符,則將它壓入棧; 當從輸入中讀到一個右分割符時,則彈出棧頂 的左分隔符,並且查看它是否和右分隔符匹配,若它們不匹配,則匹配失敗,程序報錯; 若棧頂沒有左分隔符與右分隔符匹配,或者一直存在沒有被匹配的左分隔符,左分隔符沒有被匹配,表現為所有的字符都讀入後,棧中仍然有左分隔符,則匹配失敗,程序報錯; 若所有的字符讀入結束後,棧為空,則表示匹配成功

3、代碼實現

package org.Stone6762.MStack.adopt;

import java.util.Scanner;

import org.Stone6762.MStack.imple.SeqStack;

/**
* @author_Stone6762
*/
public class MatchTest {

/**
* @LEFT記錄分隔符為“左”分隔符
*/
private final int LEFT = 0;

/**
* @RIGHT記錄分隔符為“右”分隔符
*/
private final int RIGHT = 1;

/**
* @OTHER記錄其他字符
*/
private final int OTHER = 2;

/**
* @MAXSIZE棧的大小_也就是整個程序中的左分隔符的個數的最大值
*/
private final int MAXSIZE = 100;

/**
* @Describe_判斷分隔符的類型_左_右_非法
* @param str
* @return
*/
public int verifyFlag(String str) {
if ("(".equals(str) || "[".equals(str) || "{".equals(str)
|| "/*".equals(str)) {
return LEFT;
} else if (")".equals(str) || "]".equals(str) || "}".equals(str)
|| "*/".equals(str)) {
return RIGHT;
} else {
return OTHER;

}

}

/**
* @Describe_判斷左分隔符str1和右分隔符str2是否匹配
* @param str1
* @param str2
* @return
*/
public boolean matches(String str1, String str2) {
if (("(".equals(str1) && ")".equals(str2))
|| ("{".equals(str1) && "}".equals(str2))
|| ("[".equals(str1) && "]".equals(str2))
|| ("/*".equals(str1) && "*/".equals(str2))) {
return true;
} else {
return false;
}
}

/**
* @Describe_判斷是否匹配
* @param str
* @return
* @throws Exception
*/
public boolean isLegal(String str) throws Exception {
if (!"".equals(str) && str != null) {
SeqStack S = new SeqStack(MAXSIZE);
int length = str.length();
for (int i = 0; i < length; i++) {
// 取出元素
char c = str.charAt(i);
String t = String.valueOf(c);

// 對 分隔符/**/特別處理
if (i != length) {
if ((‘/‘ == c && ‘*‘ == str.charAt(i + 1))
|| (‘*‘ == c && ‘/‘ == str.charAt(i + 1))) {
t = t.concat(String.valueOf(str.charAt(i + 1)));
i++;
}
}
// 如果是左分隔符,入棧,如果是右分隔符,出棧,看是否匹配,如果不匹配,報錯
if (LEFT == verifyFlag(t)) {
S.push(t);
} else if (RIGHT == verifyFlag(t)) {
if (S.isEmpty()) {
throw new Exception("錯誤: java語法不合法,缺少左分隔符");
} else if (!matches(S.pop().toString(), t)) {
throw new Exception("錯誤: java語法不合法,左右分隔符不匹配");
}
}
}
// 對整個語句遍歷後,如果棧非空,證明棧中還有未被匹配的左分隔符,此時是錯誤的
if (!S.isEmpty()) {
throw new Exception("錯誤: java語句不合法,缺少右分隔符");
} else {
return true;
}
} else {
throw new Exception("錯誤:Java語句為空 ! ");
}
}

public static void main(String[] args) throws Exception {
MatchTest m = new MatchTest();
Scanner scan = new Scanner(技術分享System.in);
System.out.println("請輸入 想要判斷 java語句");
while (scan.hasNext()) {
if (m.isLegal(scan.nextLine())) {
System.out.println("Java語句正確");
} else {
System.out.println("錯誤:Java語句不合法");
}
System.out.println();
System.out.println("請輸入 想要判斷 java語句");
}
}
}

棧的應用—分隔符匹配