我正在尝试将给定的数字字符串分成较小的1位数字和2位数字。 像这样:
Input : 1234
Output : (1,2,34) (1,23,4) (1,2,3,4) (12,34) (12,3,4)
我一直在尝试使用回溯来解决问题,但未能获得理想的结果。我的尝试如下:
import java.util.Arrays;
import java.util.ArrayList;
public class MyClass {
private static void func(ArrayList<String> res, String digits, String s){
if(digits.length() <= 0){
res.add(s.substring(0, s.length()-1));
return;
}
String temp = digits;
String prev_s = s;
s = s + digits.charAt(0) + ","; // chosen one character
func(res, digits.substring(1), s);
prev_s = s;
if(digits.length() >= 2){
s = s + digits.substring(0,2) + ","; // chosen two characters
func(res, digits.substring(2), s);
}
s = prev_s;
digits = temp; // unchoosing
}
public static void main(String args[]) {
String digits = "1234";
ArrayList<String> res = new ArrayList<>();
String s = "";
func(res, digits, s);
for(int i =0; i < res.size(); i++){
System.out.println(res.get(i));
}
}
}
我得到的答案如下:
1,2,3,4
1,2,3,34
1,2,23,4
1,12,3,4
1,12,3,34
我在做什么错?我想我在创建子字符串时搞砸了。
还可以在不使用回溯的情况下解决此问题吗? 谢谢!
答案 0 :(得分:2)
您的问题是还原s
的分配是错误的方法:
prev_s = s;
→s = prev_s;
仅此一项就可以解决您的问题。
除此之外:
您不需要最后两个语句。他们什么也没做。
请记住,Java是按值传递的,因此您无需在返回之前恢复参数。
您不应更改参数的值。相反,只需在递归方法调用中进行串联。
删除temp
和prev_s
,因为它们不再需要。
可以通过在逗号前面加上前缀而不是后缀来稍微简化代码。
public class MyClass {
private static void func(ArrayList<String> res, String digits, String s){
if (digits.isEmpty()) {
res.add(s.substring(1));
return;
}
func(res, digits.substring(1), s + ',' + digits.charAt(0));
if (digits.length() >= 2) {
func(res, digits.substring(2), s + ',' + digits.substring(0, 2));
}
}
public static void main(String args[]) {
ArrayList<String> res = new ArrayList<>();
func(res, "1234", "");
for (String r : res) {
System.out.println(r);
}
}
}
输出
1,2,3,4
1,2,34
1,23,4
12,3,4
12,34