[英]Java parenthesis order {[()]}
關於如何檢查括號是否平衡有很多問題,有很多答案。 但是如何找出括號的順序? 例如{}
應該在[]
之前,而[]
應該在()
之前。 任何人都可以幫助我形成一種可以為我做到這一點的方法嗎?
String parenthesis = "([{}])"
此時我正在考慮使用ArrayList<String>
類型,但如果我在(6[6{6}6]6)?
我知道如何檢查charAt(0)
,但據我所知,這就是。 任何提示都會很好。
(6[6{6}6]6)
應該變成{6[6(6)6]6}
之間的東西不變。 而且由於它基於掃描儀 class 中的用戶輸入,請告訴我一種不會限制字符長度的方法。
我會使用正則表達式來完成這項任務。 這是一個如何實現的示例:
parenthesis.matches(".*\\(.*\\[.*\\{.*\\}.*\\].*\\).*")
如果不同的括號如您在問題中描述的那樣平衡,這將返回true
,否則返回false
。 如果要自動修復這些錯誤,可以編寫替換操作:
parenthesis = parenthesis.replaceAll("(.*)[{\\[(](.*)[{\\[(](.*)[{\\[(](.*)[}\\])](.*)[}\\])](.*)[}\\])](.*)", "$1{$2[$3($4)$5]$6}$7");
這會將所有不同類型的括號替換為正確的類型,並保留其間的內容。
如果你想讓你的程序檢查更高級的東西,你使用ArrayList
的想法聽起來是最好的計划。 如果要允許多級嵌套,那么只能有兩級,但也可以有三級,並且您希望允許重新打開塊(即(a{b}c{d}e)
) ,我會使用下面的一段代碼。 請注意,這比上面的兩個正則表達式選項復雜得多,如果您可以做出一些假設,那么您可能會從中刪除一些東西。 請務必閱讀注釋,因為它們解釋了每一行代碼:
String parenthesis = "{a[b]c}(d)[e]"; //test string
ArrayList<Character> currentlyOpen = new ArrayList<>(); //all currently open parenthesis types
ArrayList<Character> opens = new ArrayList<>(); //all used open parenthesis types
Stack<Character> closes = new Stack<>(); //all used close parenthesis types
String[] openOrder = new String[] { "{", "[", "(" }; //correct open parenthesis order
String[] closeOrder = new String[] { ")", "]", "}" }; //correct close parenthesis order
Matcher regex = Pattern.compile("[{\\[()\\]}]").matcher(parenthesis); //match any open or close parenthesis type
ArrayList<String> parts = new ArrayList<>(); //list of the separate top-level groups
int removedChars = 0; //to keep track of index in the input string
while (!parenthesis.isEmpty()) {
while (regex.find()) { //iterate over all regex matches
char c = regex.group().charAt(0); //get the matched character
switch (c) {
case '}':
if (currentlyOpen.get(currentlyOpen.size() - 1) == '{') { //if the last currently open parenthesis is the correct type
currentlyOpen.remove(currentlyOpen.size() - 1); //remove this open parenthesis type from the currently open list (it is now closed)
if (!closes.contains(c)) {
closes.add(c); //add this parenthesis type to the closed parenthesis list if it's not already there
}
break;
}
throw new RuntimeException("unbalanced"); //else cough and die (or you could return false or -1 or something)
case ']': //same as the above case
if (currentlyOpen.get(currentlyOpen.size() - 1) == '[') {
currentlyOpen.remove(currentlyOpen.size() - 1);
if (!closes.contains(c)) {
closes.add(c);
}
break;
}
throw new RuntimeException("unbalanced");
case ')': //same as the above case
if (currentlyOpen.get(currentlyOpen.size() - 1) == '(') {
currentlyOpen.remove(currentlyOpen.size() - 1);
if (!closes.contains(c)) {
closes.add(c);
}
break;
}
throw new RuntimeException("unbalanced");
default: //if this is an open parenthesis
if (!opens.contains(c)) {
opens.add(c); //add this to the "all open parentheses" list if it's not already there
}
currentlyOpen.add(c); //add this to the "currently open parethesis" list
}
if (currentlyOpen.isEmpty()) { //if we are back at the top level
parts.add(parenthesis.substring(0, regex.end() - removedChars)); //add the top-level group to the list
parenthesis = parenthesis.substring(regex.end() - removedChars); //remove the top-level group from the input string
removedChars = regex.end(); //update removedChars
break; //break out of the loop and process this top-level group only
}
}
for (int i = 0; i < opens.size(); i++) { //iterate over all the open parentheses used
parts.set(parts.size() - 1, parts.get(parts.size() - 1).replace(opens.get(i).toString(), Character.toString((char) i))); //replace them all with intermediate characters (in this case numbers, you could use something else)
}
for (int i = 0; i < opens.size(); i++) { //iterate over all the open res again
parts.set(parts.size() - 1, parts.get(parts.size() - 1).replace(Character.toString((char) i), openOrder[i + openOrder.length - opens.size()])); //this time replace all the intermediate characters with the proper parentheses
}
for (int i = 0; i < closes.size(); i++) { //do the same thing for close parentheses
parts.set(parts.size() - 1, parts.get(parts.size() - 1).replace(closes.get(i).toString(), Character.toString((char) i)));
}
for (int i = 0; i < closes.size(); i++) { //do the same thing for close parentheses
parts.set(parts.size() - 1, parts.get(parts.size() - 1).replace(Character.toString((char) i), closeOrder[i]));
}
opens.clear(); //reset the list of open parenthesis types
closes.clear(); //reset the list of close parenthesis types
}
StringBuilder sb = new StringBuilder(); //use a string builder to put all the parts together again
parts.forEach(sb::append); //append all the parts to the string builder
String res = sb.toString(); //get the string from the string builder
System.out.println(res); //print it out so you can see it
如果您的示例字符串必須平衡它們,您可以使用否定字符 class [^][(){}]*
來不匹配中間的任何括號。
^\(([^]\[(){}]*)\[([^]\[(){}]*){([^]\[(){}]*)}([^]\[(){}]*)\]([^]\[(){}]*)\)$
在 Java
String regex = "^\\(([^][()\\{}]*)\\[([^][()\\{}]*)\\{([^][()\\{}]*)\\}([^][()\\{}]*)\\]([^][()\\{}]*)\\)$";
在零件
^ Start of string
\( Match ( char
( Capture group 1
[^]\[(){}]* Match any of the listed and repeat 0 or more times
) Close group
\[ Match [ char
( Capture group 2
[^]\[(){}]* Match any of the listed and repeat 0 or more times
) Close group
{ Match { char
( Capture group 3
[^]\[(){}]* Match any of the listed and repeat 0 or more times
) Close group
} Match } char
( Capture group 4
[^]\[(){}]* Match any of the listed and repeat 0 or more times
) Close group
\] Match ] char
( Capture group 5
[^]\[(){}]* Match any of the listed and repeat 0 or more times
) Close group
\) Match ) char
$ End of string
在替換中使用{$1[$2($3)$4]$5}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.