简体   繁体   中英

Find all possible string of length k with recursion

For string s = "abcd",k=3 then answer should be:

abc
abd
acd
bcd

code by java with recursion(k=3):

public class SubString {

    static ArrayList<String> al = new ArrayList<>();

    public static void main(String[] args) {
        String s = "abcd";
        findsubsequences(s, ""); // Calling a function
        for (String subString : al) {
            if (subString.length() == 3) {
                System.out.println(subString);
            }
        }
    }

    public static void findsubsequences(String s, String ans) {
        if (s.length() == 0) {
            al.add(ans);
            return;
        }
        findsubsequences(s.substring(1), ans + s.charAt(0));
        findsubsequences(s.substring(1), ans);
    }
}

I want to Find all possible substring of length k in fastest way by recursion and without foreach in arraylist

Solution using backtracking logic (can be generalized to solve any permutation / subsets / combination problems) -

public static void main(String[] args) {
    ans = new ArrayList<>();
    String s = "abcd";
    int k = 3;
    generatePermutation(new StringBuilder(""), 0, s.toCharArray(), k);
    System.out.println(ans);
}

private static List<String> ans;

private static void generatePermutation(StringBuilder temp, int st, char[] str, int k){
    if(temp.length() == k){
        // base result
        String br = temp.toString();
        ans.add(br);
        return;
    }
    
    for(int i = st; i < str.length; i++){
        temp.append(str[i]);
        generatePermutation(temp, i + 1, str, k);
        temp.setLength(temp.length() - 1);
    }
}

Output :

[abc, abd, acd, bcd]

The faster / cleaner solution is to stop iterating when you reached the maximum length. And you should only add elements if the length is correct:

public static void findsubsequences(String s, String ans, int maxLength) {
    if (s.length() == 0) {
        return;
    }
    if (ans.length() == maxLength) {
        al.add(ans);
        return;
    }
    findsubsequences(s.substring(1), ans + s.charAt(0), maxLength);
    findsubsequences(s.substring(1), ans, maxLength);
}

Additionally you could get rid of the static result list ans instead return the results:

public static void main(String[] args) {
    String s = "abcdefgh";
    List<String> results = findSubsequences(s, "", 3);
    for (String subString : results) {
        System.out.println(subString);
    }
}

public static List<String> findSubsequences(String s, String ans, int maxLength) {
    if (s.length() == 0) {
        return new ArrayList<>();
    }
    if (ans.length() == maxLength) {
        return Collections.singletonList(ans);
    }

    List<String> list = new ArrayList<>(findSubsequences(s.substring(1), ans + s.charAt(0), maxLength));
    list.addAll(findSubsequences(s.substring(1), ans, maxLength));
    return list;
}

Try this.

public static List<String> findsubsequences(String s, int k) {
    List<String> al = new ArrayList<>();
    new Object() {
        void find(int index, String ans) {
            if (index >= s.length()) {
                if (ans.length() == k)
                    al.add(ans);
                return;
            }
            find(index + 1, ans + s.charAt(index));
            find(index + 1, ans);
        }
    }.find(0, "");
    return al;
}

and

System.out.println(findsubsequences("abcd", 3));

output

[abc, abd, acd, bcd]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM