Permutations with duplicates

萝らか妹 提交于 2021-02-07 07:35:21

问题


Before I start, I have to apologize for bringing up another case of permutations with duplicates. I have gone through most of the search results and can't really find what I am looking for. I have read about the Lexicographical order and have implemented it. For this question, I am suppose to implement a recursion method that prints out the all the strings of length n consisting of just the characters a and b that have an equal number of a and b’s. The strings must be printed out one line at a time in lexical order. So, for example, a call:

printBalanced(4);

will print the strings:

aabb
abab
abba
baab
baba
bbaa

here is the code

public static void main(String[] args){
    printBalanced(4);
}


public static void printBalanced(int n){
    String letters = "";

    //string to be duplicates of "ab" depending the number of times the user wants it
    for(int i =0; i<n/2;i++){
        letters += "ab";
    }


    balanced("",letters);

}

private static void balanced(String prefix, String s){

    int len = s.length();

    //base case
    if (len ==0){
        System.out.println(prefix);
    }
    else{
            for(int i = 0; i<len; i++){     

                balanced(prefix + s.charAt(i),s.substring(0,i)+s.substring(i+1,len));


            }

        }
    }

My print results:

abab
abba
aabb
aabb
abba
abab
baab
baba
baab
baba
bbaa
bbaa
aabb
aabb
abab
abba
abab
abba
baba
baab
bbaa
bbaa
baab
baba

As you can see, I get a lot of duplicates. This is partly due to the requirement to use only characters 'a' and 'b'. The duplicates will not happen if it was "abcd" or "0123". I have read about using an arraylist and store all the results and then loop through N elements to check for duplicates and then removing it. This does not seem to be the best way to do it. Can someone share about other better solutions for this problem? =)

My Solution using SortedSet:

import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class BalancedStrings {

public static void main(String[] args){

    printBalanced(4);
}


public static void printBalanced(int n){
    String letters = "";

    for(int i =0; i<n/2;i++){
        letters += "ab";
    }


    SortedSet<String> results = balanced("",letters);
    Iterator<String> it = results.iterator();
    while (it.hasNext()) {

        // Get element and print
        Object element = it.next();
        System.out.println(element);
    }

}


//This method returns a SortedSet with permutation results. SortedSet was chosen for its sorting and not allowing
//duplicates properties.
private static SortedSet<String> balanced(String prefix, String s){

    SortedSet<String> set = new TreeSet<String>();

    int len = s.length();

    //base case
    if (len == 0){

        //return the new SortedSet with just the prefix
        set.add(prefix);
        return set;


    }
    else{

        SortedSet<String> rest = new TreeSet<String>();

        for(int i = 0; i<len; i++){

            //get all permutations and store in a SortedSet, rest
            rest = balanced(prefix + s.charAt(i),s.substring(0,i)+s.substring(i+1,len));

            //put each permutation into the new SortedSet
            set.addAll(rest);
        }

        return set;

        }
    }

}


回答1:


You can use a Set and store the results in it (preferably SortedSet) this will eliminate duplicates and maintain a sorted order as well while traversal.




回答2:


This Solution does not require the extra space for sorting

credits: http://k2code.blogspot.in/2011/09/permutation-of-string-in-java-efficient.html

public class Permutation {

    public static void printDuplicates(String str, String prefix) {
        if (str.length() == 0) {
            System.out.println(prefix); 
        }
        else {
            for (int i = 0; i < str.length(); i++) {
                if (i > 0) {
                    if (str.charAt(i) == str.charAt(i - 1)) {
                        continue; 
                    }
                }

                printDuplicates(
                    str.substring(0, i) + str.substring(i + 1, str.length()),
                    prefix + str.charAt(i)
                ); 
            }
        }
    }

    public String sort(string str) {
        // Please Implement the sorting function, I was lazy enough to do so 
    }

    public static void main(String[] args) {
        String test = "asdadsa"; 
        test = sort(test); 
        printDuplicates(test, ""); 
    }
}



回答3:


You can use the most common implementation of permutations (swap an element with the first and permute the rest). First build the string, sort it, then generate all possible permutations. Don't allow duplicates.

An implementation could be:

static String swap(String s, int i, int j) {
    char [] c = s.toCharArray();
    char tmp = c[i];
    c[i] = c[j];
    c[j] = tmp;
    return String.copyValueOf(c);
}

static void permute(String s, int start) {
    int end = s.length();

    if(start == end) {
        System.out.println(s);
        return;
    }

    permute(s, start + 1);

    for(int i = start + 1; i < end; i++) {
        if(s.charAt(start) == s.charAt(i)) continue;
        s = swap(s, start, i);
        permute(s, start + 1);
    }
}

public static void main(String [] args) {
    String s = "aabb";
    permute(s, 0);
}

Produces output:

aabb
abab
abba
baab
baba
bbaa



回答4:


Based on the code of @0605002, I modified a little bit. In the for loop of permute, we need to swap again after the permute method call. It is like backtracking. We need to swap it back for next iteration.

static void permute(String s, int start) {
    int end = s.length();

    if(start == end) {
        System.out.println(s);
        return;
    }

    permute(s, start + 1);

    for(int i = start + 1; i < end; i++) {
        if(s.charAt(start) == s.charAt(i)) continue;
        s = swap(s, start, i);
        permute(s, start + 1);
        s = swap(s, start, i);
    }
}


来源:https://stackoverflow.com/questions/12667551/permutations-with-duplicates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!