请原谅我,如果我搞砸了,这是我的第一个问题。我一直在研究这个问题几个小时。它应该使用递归生成字符串中的所有字符子集( 不一定是子串 )。我评论了很多,所以你可以看到我的想法,并希望告诉我哪里出错了。我正在使用Eclipse作为IDE,如果这有任何区别的话。
import java.util.ArrayList;
//Generates subsets of a string
public class SubsetGenerator
{
private String original;
private String remaining;
private ArrayList<String> subsets;
//Constructs a subset generator
//@param input string to have subsets generated
public SubsetGenerator(String input)
{
original = input;
remaining = original;
subsets = new ArrayList<String>();
}
public void printSubsets()
{
System.out.print(subsets);
}
//gets subsets
public void generateSubsets()
{
//if the string is empty, it has no subsets
if(remaining.length() == 1)
{
subsets.add(remaining);
return;
}
else
{
//remove the first character and hold onto it
String removed = remaining.substring(0,1);
remaining = remaining.substring(1);
//recursion. Eventually it should add the last character in the string to the ArrayList and return
generateSubsets();
//Take each element that is in the ArrayList, add the removed character to it, add this back to the list
for (int i = 0; i < subsets.size(); i++)
{
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);//add the removed character by itself
return;
}
}
}
这些是我得到的错误:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3221)
at java.lang.String.<init>(String.java:233)
at java.lang.StringBuilder.toString(StringBuilder.java:447)
at SubsetGenerator.generateSubsets(SubsetGenerator.java:41)
at SubsetGenerator.generateSubsets(SubsetGenerator.java:37)
at SubsetGenerator.generateSubsets(SubsetGenerator.java:37)
at SubsetGenerator.generateSubsets(SubsetGenerator.java:37)
at SubsetGeneratorTester.main(SubsetGeneratorTester.java:7)
我用这段代码测试了它:
public class SubsetGeneratorTester
{
public static void main(String[] args)
{
SubsetGenerator s = new SubsetGenerator("world");
s.generateSubsets();
s.printSubsets();
}
}
答案 0 :(得分:1)
这里你去:
public class SubsetGenerator {
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> list = new ArrayList<String>();
StringBuilder myBuilder = new StringBuilder();
String original = "World";
for(int i=0; i<original.length(); ++i)
genSubs(original, myBuilder, list, i);
System.out.println(list.toString());
}
static void genSubs(String original, StringBuilder current, ArrayList<String> myList, int index){
current.append(original.charAt(index));
System.out.println(current.toString() + index);
myList.add(current.toString());
for(int i=index+1; i<original.length(); ++i)
genSubs(original, current, myList, i);
current.deleteCharAt(current.toString().length()-1);
return;
}
}
输出:
[W, Wo, Wor, Worl, World, Word, Wol, Wold, Wod, Wr, Wrl, Wrld, Wrd, Wl, Wld, Wd, o, or, orl, orld, ord, ol, old, od, r, rl, rld, rd, l, ld, d]
答案 1 :(得分:0)
您应该将剩余的字符串作为参数传递给generateSubsets(剩余)方法。您正在访问每次递归调用时剩余的相同副本,它始终等于原始,并且它永远不会达到remaining.length()== 1的条件。您应该将修改后的剩余字符串传递给generateSubsets()。
修改是的,你是对的。我发现了这个问题。它在你的for循环中。每次向子集添加项目时,其大小都会不断增加。因此,循环变为无限循环。进行此更改
int size = subset.size()
for(int i =0; i< size; i++)
{..}
答案 2 :(得分:0)
我宁愿建议从初始String创建字符数组并使用该数组。创建大量子串并不是最好的选择。
此外,您可以增加传递jvm参数的可用内存,例如 -Xmx1g -XX:MaxPermSize = 512m -XX:MaxHeapSize = 256m
答案 3 :(得分:-1)
我不太清楚你在寻找什么结果......但如果不是这样的话,我相信我能按照你想要的方式得到它。请给我们一个示例数据和结果。
public void GetSubsets(String str, ArrayList list)
{
if(str.length() > 0 && list != null)
{
list.add(str);
GetSubsets(str.substring(1), list);
}
}
“世界”的输出是:
ArrayList list = new ArrayList();
GetSubsets("World", list);
System.out.println(list.toString());
“[World,orld,rld,ld,d]”
当发送空字符串或空列表时,此代码也不执行任何操作。如果你愿意,可以编辑清单。