简体   繁体   English

使用递归JAVA生成字符串中所有字符子集

[英]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.

相关问题 java向量递归解生成子集有不同的结果 - java vector recursion solution generating subsets have different results java - 如何使用递归使回文程序忽略java中字符串所有位置的特殊字符? - How to make palindrome program using recursion ignore special characters in all places of the string in java? 给定一个整数数组(长度为 n),使用 Java 中的递归查找并返回输入数组的所有子集 - Given an integer array (of length n), find and return all the subsets of input array using recursion in Java Java中的递归字符串并删除字符 - Recursion String in Java and removing characters Java递归-计算字符串中的字符 - Java Recursion - counting Characters in a string Java:使用Java 8 API对非连续字符串字符子集进行排序的更快方法是什么 - Java: What's the faster way to sort subsets of non-consecutive string characters using Java 8 API Java - 递归地查找String(powerset)的所有子集 - Java - Finding all subsets of a String (powerset) recursively 用于查找字符串子集的无限递归? - Infinite Recursion for finding the subsets of a string? 使用Gosper&#39;s Hack(Bankers序列)生成所有子集 - Generating all subsets using Gosper's Hack (Bankers sequence) Java - 使用递归从字符串创建所有子字符串 - Java - using recursion to create all substrings from a string
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM