Java 根据括号中的数字*内容展开给定字符串
我试着取一个给定的字符串,当括号前有一个数字时,括号内的内容就会重复这个次数。我考虑过使用StringBuilder并构建这个函数,但我不确定如何重复括号内的内容。 示例-3(ab)-结果将是ababab,示例-3(b(2(c))结果将是bcc 在我在这里构建的函数中,它重复括号,而不是括号的内容Java 根据括号中的数字*内容展开给定字符串,java,string,algorithm,stringbuilder,expansion,Java,String,Algorithm,Stringbuilder,Expansion,我试着取一个给定的字符串,当括号前有一个数字时,括号内的内容就会重复这个次数。我考虑过使用StringBuilder并构建这个函数,但我不确定如何重复括号内的内容。 示例-3(ab)-结果将是ababab,示例-3(b(2(c))结果将是bcc 在我在这里构建的函数中,它重复括号,而不是括号的内容 public static String solve(String s){ StringBuilder sb = new StringBuilder(); int repeat =
public static String solve(String s){
StringBuilder sb = new StringBuilder();
int repeat = 0;
for (char c : s.toCharArray()) {
if (Character.isDigit(c)) {
repeat = repeat * 10 + Character.getNumericValue(c);
} else {
while (repeat > 0) {
sb.append(c);
repeat--;
}
sb.append(c);
}
}
return sb.toString();
}
}
您需要一个堆栈来维护从最内层到最外层容器所需操作的内存 以下是Python中的代码:
def parenthesis_printer(s):
L = [""] # maintains the stack of the string-containers
N = [1] # maintains the stack of the print-multiplier needed for the corresponding string-container
nstr = ""
for i in range(len(s)):
if s[i].isnumeric():
nstr += s[i]
elif s[i] == '(':
nstr = "1" if len(nstr) == 0 else nstr
nval = int(nstr)
N.append(nval)
L.append("")
nstr = ""
elif s[i] == ')':
nval = N.pop()
lval = L.pop()
lstr = "".join([lval for _ in range(nval)])
L[-1] += lstr
else:
L[-1] += s[i]
return L[-1]
print(parenthesis_printer("3(b(2(c)))"))
输出:
bccbccbcc
3 0 [][]
( 3 [][]
b 0 [3][, ]
( 0 [3][, b]
2 0 [3, 1][, b, ]
( 2 [3, 1][, b, ]
c 0 [3, 1, 2][, b, , ]
) 0 [3, 1, 2][, b, , c]
) 0 [3, 1][, b, cc]
) 0 [3][, bcc]
这个问题自然是递归的。保留您已经开始的方法,您可以编写如下内容。在实际代码中,我可能倾向于一种分离标记化和解析的方法,这意味着我将执行两个单独的过程:第一个过程是将输入字符串转换为标记,第二个过程是从标记流生成输出
公共静态对求解(字符串s,int start){
int repeat=0;
字符串ret=“”;
对于(int i=start;i0){
ret+=内部第一;
}
repeat=0;//确保循环后面的'repeat'不是-1。
i=内秒;
}如果(c=='),则为else){
返回新的一对(ret,i);
}否则{
ret+=c;
}
}
返回新的一对(ret,s.length());
}
将此代码转换为使用单个StringBuilder
——以避免冗余字符串副本——留作练习
上面使用了一个简单的
Pair
helper类。由于Java没有附带一个(groan),这里有一个非常简单的实现,可以与上面的代码一起使用;您还可以使用JavaFX的JavaFX.util.Pair
或java.util.AbstractMap.SimpleEntry
或其他任何东西
静态类对{
最后的T第一;
最后一秒;
成对(T、f、U、s){
第一个=f;
秒=秒;
}
}
与的答案基本相同,但使用java,并带有一点调试输出,以查看代码的行为:
public static String solve(String s)
{
Stack<Integer> countStack = new Stack<>(); // stack for counting
Stack<StringBuilder> stubs = new Stack<>(); // stack for parts of the string that were processed
stubs.push(new StringBuilder());
int count = 0;
for(char c : s.toCharArray())
{
System.out.println(Character.toString(c) + " " + count + " " + countStack + stubs);
if(Character.isDigit(c))
{
// part of a count (assumes digits are never part of the actual output-string)
count = count * 10 + (c - '0');
}
else if(c == '(')
{
// encountered the start of a new repeated group
if(count == 0)
// no count specified, assume a count of one
countStack.push(1);
else
// push the count for this group
countStack.push(count);
// push a new stringbuilder that will contain the new group
stubs.push(new StringBuilder());
count = 0; // reset count
}
else if(c == ')')
{
// group terminated => repeat n times and append to new group one above
String tmp = stubs.pop().toString();
int ct = countStack.pop();
for(int i = 0; i < ct; i++)
stubs.peek().append(tmp);
}
else
{
// just a normal character, append to topmost group
stubs.peek().append(c);
count = 0;
}
}
// if the string was valid there's only the output-string left on the stubs-list
return stubs.peek().toString();
}
返回:
bccbccbcc
这里有点棘手的部分是找到匹配的论题。最简单的方法可能是使用多个过程,其中每个过程只替换在下一个结束过程之前没有开始过程的部分。当没有多余的偏执词时,或者您发现语法错误(例如,只剩下一个偏执词)时,您可以停止操作。括号前面的数字始终是一位数字,或者
12(b)
也是有效的输入吗?数字也可以出现在括号前面以外的地方;e、 g.3(a4b)
?输入将仅由有效括号中的小写字母和数字(1到9)组成。最后一个右括号后面将没有字母或数字。仅就上下文而言,更一般的任务称为解析或构建or。这方面有一些库,但对于相对简单的语法来说,它们可能有些过头了。构建树结构可以让您在一次过程中完成这项工作。(你不需要准确地创建树,但它可以帮助你考虑递归的方法)。像你的第二个例子:3(b(2(c))
=>3(b(cc))
?这个想法很容易转移到Java。逻辑保持不变。是N和L字符串还是字符串数组?每个循环在哪里结束?N和L是堆栈。N维护数字乘法器,L维护相应容器中的字符串,因此堆栈代替了stringbuilder?我尝试使用导入,但它似乎给了我错误提示eclipse@rokkcrow什么错误?您是如何尝试使用它的?我复制了import和import javafx.util.Pair;在类之前,它给我错误,当我输入代码时,它不是一个导入options@rokkcrow再说一遍,什么错误?您使用的是什么Java版本?(JavaFX在Java11中被删除了,但是还有其他简单的方法来替换对类。)我正在使用EclipseIDE以这种方式创建大量新的字符串生成器是cargo cult编程;它实际上比使用字符串连接效率低。好的。我尝试了这个方法,但在这个例子中预期:但是是:有没有一种方法可以不删除[]的内容,我想它是从您使用的pop函数中删除的呢given:4(1(5b(n(j)))输出:bnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjbnjj]@Paul checkplease@KonradRudolph那么像往常一样,,该代码旨在演示一个原则,而不是最有效的解决方案。有很多地方可以对其进行优化,但至少IMO的可读性优于性能