Java高效的括号匹配方法组输入
编辑:我应该提到程序必须是严格非递归的 我正在尝试创建一个方法,将组分配给匹配的括号。例如,输入:Java高效的括号匹配方法组输入,java,parentheses,Java,Parentheses,编辑:我应该提到程序必须是严格非递归的 我正在尝试创建一个方法,将组分配给匹配的括号。例如,输入:m(a(bc)(d(e(f g h)i)j)k)n输出为: Inputted text: m (a (b c) (d (e (f g h) i) j) k) n group 0 = m (a (b c) (d (e (f g h) i) j) k) n group 1 = (a (b c) (d (e (f g h) i) j) k) group 2 = (b c) group 3 = (d (e
m(a(bc)(d(e(f g h)i)j)k)n
输出为:
Inputted text: m (a (b c) (d (e (f g h) i) j) k) n
group 0 = m (a (b c) (d (e (f g h) i) j) k) n
group 1 = (a (b c) (d (e (f g h) i) j) k)
group 2 = (b c)
group 3 = (d (e (f g h) i) j)
group 4 = (e (f g h) i)
group 5 = (f g h)
我创建了以下方法,但正如您所看到的,它将第一个遇到的左括号与第一个遇到的右括号相匹配,而不是每个左括号表示新组的开始。我无法找到一种简单的方法来复制上述输出而不重新开始。有什么想法吗
public class Matching {
public static String[] group(String s){
Stack<Integer> indexStack = new Stack<Integer>();
String[] groupArray = new String[15];
int count = 0;
for(int i = 0; i != s.length(); i++){
/*
* If character in index position is a left parenthesis, push the current
* index onto stack. If a right parenthesis is encountered, pop the stack and
* store its index temporarily. Use index and current position at right
* parenthesis to create a substring.
*/
if(s.charAt(i) == '(')
indexStack.push(i);
else if( s.charAt(i) == ')' ){
try{
int index = indexStack.pop();
groupArray[count++] = s.substring(index, i + 1);
}
catch(Exception e){ //An exception results from popping empty stack
System.out.println("Unbalanced in input " + s +
" at index " + i + "\n");
return null; //return null to caller
}
}
}
//If stack not empty at the end of loop, return null to caller
if(!indexStack.isEmpty()){
System.out.println("Unbalanced in input " + s +
" at index " + indexStack.pop() + "\n");
return null;
}
//initial input that starts with a character other than ( needed to be added.
if (s.charAt(0) != '(')
groupArray[count++] = s;
return groupArray;
}
}
公共类匹配{
公共静态字符串[]组(字符串s){
Stack indexStack=新堆栈();
String[]groupArray=新字符串[15];
整数计数=0;
对于(int i=0;i!=s.length();i++){
/*
*如果索引位置的字符是左括号,则按当前
*索引到堆栈上。如果遇到右括号,请弹出堆栈并
*临时存储其索引。使用索引和右侧的当前位置
*用括号创建子字符串。
*/
如果(s.charAt(i)='(')
指数稳定推力(i);
如果(s.charAt(i)=')'){
试一试{
int index=indexStack.pop();
groupArray[count++]=s.substring(索引,i+1);
}
catch(异常e){//弹出空堆栈导致异常
System.out.println(“输入不平衡”+s+
“在索引“+i+”\n”);
return null;//将null返回给调用方
}
}
}
//如果堆栈在循环结束时不为空,则向调用者返回null
如果(!indexStack.isEmpty()){
System.out.println(“输入不平衡”+s+
“at index”+indexStack.pop()+“\n”);
返回null;
}
//以除(需要添加)以外的字符开头的初始输入。
如果(s.charAt(0)!='(')
groupArray[count++]=s;
返回组数组;
}
}
导入java.util.Stack;
公共类匹配{
公共静态字符串[]组(字符串s){
Stack indexStack=新堆栈();
String[]groupArray=新字符串[15];
int[]tracker=new int[s.length()];//用于正确分组的帮助器
整数计数=0;
对于(int i=0;i!=s.length();i++){
/*
*如果索引位置的字符是左括号,则按当前
*索引到堆栈上。如果遇到右括号,请弹出堆栈并
*临时存储其索引。使用索引和右侧的当前位置
*用括号创建子字符串。
*/
如果(s.charAt(i)='('){
指数稳定推力(i);
tracker[count++]=i;//左括号表示一个新组
}
如果(s.charAt(i)=')'){
试一试{
int index=indexStack.pop();
int j=0;//查找数组中相应索引的位置
while(跟踪器[j]!=索引)
j++;
groupArray[j]=s.substring(索引,i+1);
}
catch(异常e){//弹出空堆栈导致异常
System.out.println(“输入不平衡”+s+
“在索引“+i+”\n”);
return null;//将null返回给调用方
}
}
}
//如果堆栈在循环结束时不为空,则向调用者返回null
如果(!indexStack.isEmpty()){
System.out.println(“输入不平衡”+s+
“at index”+indexStack.pop()+“\n”);
返回null;
}
//以除(需要添加)以外的字符开头的初始输入。
如果(s.charAt(0)!='(')
groupArray[count++]=s;
返回组数组;
}
}
我用另一个数组来跟踪左括号的出现,为这个问题添加了一个非常糟糕的解决方案。如果我的教授看到了这一点,我就没有作弊。当我更改代码的输入时,我收到了一个错误。另外,在
sys.out
上有多余的空值
我没有尝试修复您的代码,但您可以采用以下方法进行分组:
import java.util.ArrayList;
import java.util.HashMap;
public class Match {
public static void main(String[] args) {
match("m(a(bc)(d(e(fgh)i)j)k)n");
}
public static void match(String string) {
final int stringLength = string.length();
final HashMap<Integer, Group> group = new HashMap<Integer, Group>();
final ArrayList<Integer> counter = new ArrayList<Integer>();
group.put(0, new Group(0, stringLength - 1));
for (int i = 0; i < stringLength; i++) {
final char charAt = string.charAt(i);
if (charAt == '(') {
group.put(i, new Group(i, 0));
counter.add(i);
} else if (charAt == ')') {
final int counterIndex = counter.size() - 1;
group.get(counter.get(counterIndex)).end = i;
counter.remove(counterIndex);
}
}
for (Group g : group.values())
System.out.println(g.start + " --- " + g.end);
}
}
class Group {
int start;
int end;
Group(int s, int e) {
this.start = s;
this.end = e;
}
}
import java.util.ArrayList;
导入java.util.HashMap;
公开课比赛{
公共静态void main(字符串[]args){
匹配(“m(a(bc)(d(e(fgh)i)j)k)n”);
}
公共静态无效匹配(字符串){
final int stringLength=string.length();
最终HashMap组=新HashMap();
最终ArrayList计数器=新ArrayList();
put(0,新组(0,stringLength-1));
对于(int i=0;i
您将获得组的起点和终点,然后可以根据需要
sys.out
。更好的工作方式是使用正则表达式和递归。这减少了代码长度,并利用了java提供的实用程序
package test;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Grouping {
static Pattern pattern = Pattern.compile("(\\(.*\\))");
static Pattern subPattern = Pattern.compile("^(\\((\\w|\\s)*\\))");
static Matcher matcher;
static Matcher subMatcher;
public static void main(String[] args) {
String STRING_GROUP = "m (a (b c) (d (e (f g h) i) j) k) n";
findMatchingGroup(STRING_GROUP);
}
public static void findMatchingGroup(String STRING_GROUP) {
matcher = pattern.matcher(STRING_GROUP);
// System.out.println("STRING : " + STRING_GROUP);
while (matcher.find()) {
String group = matcher.group(1);
boolean ifSubString = false;
subMatcher = subPattern.matcher(group);
/**
* I am trying to find if a subgroup exists at the beginning of the
* string if yes then processes the string after the group. else cut
* the string from both the ends to eliminate parenthesis for the
* next iteration
*/
if (subMatcher.find()) {
System.out.println(subMatcher.group(1));
ifSubString = true;
findMatchingGroup(matcher.group(1).substring(
subMatcher.group(1).length() - 1));
} else {
System.out.println(group);
}
if (ifSubString == false) {
findMatchingGroup(group.substring(1, group.length() - 2));
}
}
}
}
不需要使用递归。
输出元素的if顺序
package test;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Grouping {
static Pattern pattern = Pattern.compile("(\\(.*\\))");
static Pattern subPattern = Pattern.compile("^(\\((\\w|\\s)*\\))");
static Matcher matcher;
static Matcher subMatcher;
public static void main(String[] args) {
String STRING_GROUP = "m (a (b c) (d (e (f g h) i) j) k) n";
findMatchingGroup(STRING_GROUP);
}
public static void findMatchingGroup(String STRING_GROUP) {
matcher = pattern.matcher(STRING_GROUP);
// System.out.println("STRING : " + STRING_GROUP);
while (matcher.find()) {
String group = matcher.group(1);
boolean ifSubString = false;
subMatcher = subPattern.matcher(group);
/**
* I am trying to find if a subgroup exists at the beginning of the
* string if yes then processes the string after the group. else cut
* the string from both the ends to eliminate parenthesis for the
* next iteration
*/
if (subMatcher.find()) {
System.out.println(subMatcher.group(1));
ifSubString = true;
findMatchingGroup(matcher.group(1).substring(
subMatcher.group(1).length() - 1));
} else {
System.out.println(group);
}
if (ifSubString == false) {
findMatchingGroup(group.substring(1, group.length() - 2));
}
}
}
}
private List<String> findSubSets(final String expresion) {
final List<String> result = new ArrayList<>();
final Stack<StringBuilder> stack = new Stack<>();
StringBuilder builder = new StringBuilder();
for (char c : expresion.toCharArray()) {
if (c == '(') {
stack.push(builder);
builder = new StringBuilder();
}
builder.append(c);
if (c == ')') {
final String value = builder.toString();
final StringBuilder parent = stack.pop();
parent.append(value);
result.add(value);
builder = parent;
}
}
if (!expresion.startsWith("(")) {
result.add(builder.toString());
}
return result;
}
Group 0 = (b c)
Group 1 = (f g h)
Group 2 = (e (f g h) i)
Group 3 = (d (e (f g h) i) j)
Group 4 = (a (b c) (d (e (f g h) i) j) k)
Group 5 = m (a (b c) (d (e (f g h) i) j) k) n