2

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

vishal
  • 157
  • 1
  • 10
dd000
  • 21
  • 2
  • 1
    And what is the question / problem? Does the code not work? Not fast / efficient enough? – luk2302 May 24 '21 at 08:09
  • i dont want to use foreach in main method, i need a method like findsubsequences(String s, int k) to Find all possible substring of length k – dd000 May 24 '21 at 08:20
  • then you should check the length of `ans` in `findsubsequences` and stop going deeper when `ans` is long enough. – luk2302 May 24 '21 at 08:21
  • can you help me write specifically, sorry if my English is not good – dd000 May 24 '21 at 08:26

2 Answers2

2

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]
vishal
  • 157
  • 1
  • 10
  • Instead of `temp.setLength(temp.length()-1)` use `temp.deleteChartAt(temp.length()-1)` to be much more obvious. – SomeDude May 24 '21 at 13:02
0

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;
}
luk2302
  • 55,258
  • 23
  • 97
  • 137