Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

permutations of a string using iteration

I'm trying to find permutation of a given string, but I want to use iteration. The recursive solution I found online and I do understand it, but converting it to an iterative solution is really not working out. Below I have attached my code. I would really appreciate the help:

public static void combString(String s) {
    char[] a = new char[s.length()];
    //String temp = "";
    for(int i = 0; i < s.length(); i++) {
        a[i] = s.charAt(i);
    }
    for(int i = 0; i < s.length(); i++) {
        String temp = "" + a[i];    

        for(int j = 0; j < s.length();j++) {
            //int k = j;
            if(i != j) {
                System.out.println(j);
                temp += s.substring(0,j) + s.substring(j+1,s.length());
            }               
        }
        System.out.println(temp);
    }
}
like image 362
ueg1990 Avatar asked Aug 11 '12 13:08

ueg1990


People also ask

How do you print permutations of a string using recursion?

Method 1(Using Recursion) :Create a recursive function say permute(string s, int l, int r), and pass string along with starting index of the string and the ending index of the string. Base condition will be if(l==r) then print the s. Otherwise, run a loop from [l, r] And, swap(s[l], s[i])

What is a permutation of a string?

A Permutation of a string is another string that contains same characters, only the order of characters can be different. For example, “abcd” and “dabc” are Permutation of each other.

What is permutation of string in Java?

Permutation of the string means all the possible new strings that can be formed by interchanging the position of the characters of the string. For example, string ABC has permutations [ABC, ACB, BAC, BCA, CAB, CBA].


3 Answers

Following up on my related question comment, here's a Java implementation that does what you want using the Counting QuickPerm Algorithm:

public static void combString(String s) {
    // Print initial string, as only the alterations will be printed later
    System.out.println(s);   
    char[] a = s.toCharArray();
    int n = a.length;
    int[] p = new int[n];  // Weight index control array initially all zeros. Of course, same size of the char array.
    int i = 1; //Upper bound index. i.e: if string is "abc" then index i could be at "c"
    while (i < n) {
        if (p[i] < i) { //if the weight index is bigger or the same it means that we have already switched between these i,j (one iteration before).
            int j = ((i % 2) == 0) ? 0 : p[i];//Lower bound index. i.e: if string is "abc" then j index will always be 0.
            swap(a, i, j);
            // Print current
            System.out.println(join(a));
            p[i]++; //Adding 1 to the specific weight that relates to the char array.
            i = 1; //if i was 2 (for example), after the swap we now need to swap for i=1
        }
        else { 
            p[i] = 0;//Weight index will be zero because one iteration before, it was 1 (for example) to indicate that char array a[i] swapped.
            i++;//i index will have the option to go forward in the char array for "longer swaps"
        }
    }
}

private static String join(char[] a) {
    StringBuilder builder = new StringBuilder();
    builder.append(a);
    return builder.toString();
}

private static void swap(char[] a, int i, int j) {
    char temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}
like image 99
Don Roby Avatar answered Oct 15 '22 20:10

Don Roby


    List<String> results = new ArrayList<String>();
    String test_str = "abcd";
    char[] chars = test_str.toCharArray();
    results.add(new String("" + chars[0]));
    for(int j=1; j<chars.length; j++) {
        char c = chars[j];
        int cur_size = results.size();
        //create new permutations combing char 'c' with each of the existing permutations
        for(int i=cur_size-1; i>=0; i--) {
            String str = results.remove(i);
            for(int l=0; l<=str.length(); l++) {
                results.add(str.substring(0,l) + c + str.substring(l));
            }
        }
    }
    System.out.println("Number of Permutations: " + results.size());
    System.out.println(results);

Example: if we have 3 character string e.g. "abc", we can form permuations as below.

1) construct a string with first character e.g. 'a' and store that in results.

    char[] chars = test_str.toCharArray();
    results.add(new String("" + chars[0]));

2) Now take next character in string (i.e. 'b') and insert that in all possible positions of previously contsructed strings in results. Since we have only one string in results ("a") at this point, doing so gives us 2 new strings 'ba', 'ab'. Insert these newly constructed strings in results and remove "a".

    for(int i=cur_size-1; i>=0; i--) {
        String str = results.remove(i);
        for(int l=0; l<=str.length(); l++) {
            results.add(str.substring(0,l) + c + str.substring(l));
        }
    }

3) Repeat 2) for every character in the given string.

for(int j=1; j<chars.length; j++) {
    char c = chars[j];
     ....
     ....
}

This gives us "cba", "bca", "bac" from "ba" and "cab", "acb" and "abc" from "ab"

like image 23
Deeps Avatar answered Oct 15 '22 21:10

Deeps


Work queue allows us to create an elegant iterative solution for this problem.

static List<String> permutations(String string) {
    List<String> permutations = new LinkedList<>();
    Deque<WorkUnit> workQueue = new LinkedList<>(); 

    // We need to permutate the whole string and haven't done anything yet.
    workQueue.add(new WorkUnit(string, ""));

    while (!workQueue.isEmpty()) { // Do we still have any work?
        WorkUnit work = workQueue.poll();

        // Permutate each character.
        for (int i = 0; i < work.todo.length(); i++) {
            String permutation = work.done + work.todo.charAt(i);

            // Did we already build a complete permutation?
            if (permutation.length() == string.length()) {
                permutations.add(permutation);
            } else {

                // Otherwise what characters are left? 
                String stillTodo = work.todo.substring(0, i) + work.todo.substring(i + 1);
                workQueue.add(new WorkUnit(stillTodo, permutation));
            }
        }
    }
    return permutations; 
}

A helper class to hold partial results is very simple.

/**
 * Immutable unit of work
 */
class WorkUnit {
    final String todo;
    final String done;

    WorkUnit(String todo, String done) {
        this.todo = todo;
        this.done = done;
    }
}

You can test the above piece of code by wrapping them in this class.

import java.util.*;

public class AllPermutations {

    public static void main(String... args) {
        String str = args[0];
        System.out.println(permutations(str));
    }

    static List<String> permutations(String string) {
        ...
    }
}

class WorkUnit {
    ...
}

Try it by compiling and running.

$ javac AllPermutations.java; java AllPermutations abcd

The below implementation can also be easily tweaked to return a list of permutations in reverse order by using a LIFO stack of work instead of a FIFO queue.

like image 3
Alex Yursha Avatar answered Oct 15 '22 21:10

Alex Yursha