[英]Generating all subsets of characters in a string using recursion, JAVA
Forgive me if I mess this up, this is my first question. 如果我搞砸了,请原谅我,这是我的第一个问题。 I've been working on this problem for hours.
我已经在这个问题上工作了几个小时了。 It is supposed to generate all subsets of characters ( not necessarily substrings ) in a string, using recursion.
应该使用递归来生成字符串中字符的所有子集( 不一定是子字符串 )。 I commented it a lot so you could see my thinking and hopefully tell me where I'm going wrong.
我评论了很多,以便您可以看到我的想法,并希望告诉我我要去哪里了。 I'm using Eclipse as an IDE if that makes any difference.
如果有什么不同,我正在使用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;
}
}
}
These are the errors I'm getting: 这些是我得到的错误:
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)
I've tested it with this code: 我已经用以下代码对其进行了测试:
public class SubsetGeneratorTester
{
public static void main(String[] args)
{
SubsetGenerator s = new SubsetGenerator("world");
s.generateSubsets();
s.printSubsets();
}
}
Here ya go: 你去:
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;
}
}
Output: 输出:
[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]
You should pass the remaining string as argument to generateSubsets(remaining) method. 您应该将剩余的字符串作为参数传递给generateSubsets(remaining)方法。 You are accessing the same copy of remaining on every recursion call and it always equal to original and it never hit the condition where remaining.length() == 1. You should pass the modified remaining string to generateSubsets().
您在每个递归调用上都访问剩余的相同副本,并且该副本始终等于原始副本,并且永远不会达到剩余.length()== 1的条件。您应该将修改后的剩余字符串传递给generateSubsets()。
Edit yes you are right. 编辑是的,你是对的。 I found the problem.
我发现了问题。 It's in your for loop.
它在您的for循环中。 Every time you are adding an item to your subset, it size keep increasing.
每次将项目添加到子集中时,它的大小都会不断增加。 So for loop becomes infinite loop.
因此for循环变为无限循环。 Make this change
进行更改
int size = subset.size()
for(int i =0; i< size; i++)
{..}
I would rather recommend to create characters array from the initial String and use the array. 我宁愿建议从初始String创建字符数组并使用该数组。 Creating plenty of substrings is no the best choice here.
创建大量的子字符串并不是这里的最佳选择。
Also you can increase available memory passing jvm arguments eg -Xmx1g -XX:MaxPermSize=512m -XX:MaxHeapSize=256m 另外,您还可以增加传递jvm参数的可用内存,例如-Xmx1g -XX:MaxPermSize = 512m -XX:MaxHeapSize = 256m
I'm not quite sure what result you are looking for .... but if this is not it I am sure I can get it the way you want. 我不太确定您要寻找什么结果....但是如果不是这样,我相信我可以按照您想要的方式获得它。 Please give us a example data and result.
请给我们一个示例数据和结果。
public void GetSubsets(String str, ArrayList list)
{
if(str.length() > 0 && list != null)
{
list.add(str);
GetSubsets(str.substring(1), list);
}
}
the output for "World" is: “世界”的输出为:
ArrayList list = new ArrayList();
GetSubsets("World", list);
System.out.println(list.toString());
"[World, orld, rld, ld, d]" “ [世界,世界,奥尔德,rld,ld,d]”
This code also does nothing when there is a empty string sent, or null list. 当发送空字符串或空列表时,此代码也不执行任何操作。 edit out the list check if you please.
编辑清单,请检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.