找出弦的所有排列的优雅方法是什么。例如,ba的排列,将是ba和ab,但更长的字符串,如abcdefgh?是否有Java实现示例?


当前回答

使用递归的简单python解决方案。

def get_permutations(string):

    # base case
    if len(string) <= 1:
        return set([string])

    all_chars_except_last = string[:-1]
    last_char = string[-1]

    # recursive call: get all possible permutations for all chars except last
    permutations_of_all_chars_except_last = get_permutations(all_chars_except_last)

    # put the last char in all possible positions for each of the above permutations
    permutations = set()
    for permutation_of_all_chars_except_last in permutations_of_all_chars_except_last:
        for position in range(len(all_chars_except_last) + 1):
            permutation = permutation_of_all_chars_except_last[:position] + last_char + permutation_of_all_chars_except_last[position:]
            permutations.add(permutation)

    return permutations

其他回答

使用递归的简单python解决方案。

def get_permutations(string):

    # base case
    if len(string) <= 1:
        return set([string])

    all_chars_except_last = string[:-1]
    last_char = string[-1]

    # recursive call: get all possible permutations for all chars except last
    permutations_of_all_chars_except_last = get_permutations(all_chars_except_last)

    # put the last char in all possible positions for each of the above permutations
    permutations = set()
    for permutation_of_all_chars_except_last in permutations_of_all_chars_except_last:
        for position in range(len(all_chars_except_last) + 1):
            permutation = permutation_of_all_chars_except_last[:position] + last_char + permutation_of_all_chars_except_last[position:]
            permutations.add(permutation)

    return permutations

基于Mark Byers的回答,我想出了这个解决方案:

JAVA

public class Main {

    public static void main(String[] args) {
        myPerm("ABCD", 0);
    }

    private static void myPerm(String str, int index)
    {
        if (index == str.length()) System.out.println(str);

        for (int i = index; i < str.length(); i++)
        {
            char prefix = str.charAt(i);
            String suffix = str.substring(0,i) + str.substring(i+1);

            myPerm(prefix + suffix, index + 1);
        }
    }
}

C#

我还使用新的c# 8.0范围操作符在c#中编写了该函数

    class Program
    {
        static void Main(string[] args)
        {
            myPerm("ABCD", 0);
        }

        private static void myPerm(string str, int index)
        {
            if (index == str.Length) Console.WriteLine(str);

            for (int i = index; i < str.Length; i++)
            {
                char prefix = str[i];
                string suffix = str[0..i] + str[(i + 1)..];

                myPerm(prefix + suffix, index + 1);
            }
        }
    

我们只是把每个字母放在开头,然后排列。 第一次迭代是这样的:

/*
myPerm("ABCD",0)  
  prefix = "A"  
  suffix = "BCD"  
  myPerm("ABCD",1)  
    prefix = "B"  
    suffix = "ACD"  
    myPerm("BACD",2)  
      prefix = "C"  
      suffix = "BAD"  
      myPerm("CBAD",3)  
        prefix = "D"  
        suffix = "CBA"  
        myPerm("DCBA",4)  
          Console.WriteLine("DCBA")
*/

使用递归。

当输入是空字符串时,唯一的排列就是空字符串。尝试将字符串中的每个字母作为第一个字母,然后使用递归调用找到其余字母的所有排列。

import java.util.ArrayList;
import java.util.List;

class Permutation {
    private static List<String> permutation(String prefix, String str) {
        List<String> permutations = new ArrayList<>();
        int n = str.length();
        if (n == 0) {
            permutations.add(prefix);
        } else {
            for (int i = 0; i < n; i++) {
                permutations.addAll(permutation(prefix + str.charAt(i), str.substring(i + 1, n) + str.substring(0, i)));
            }
        }
        return permutations;
    }

    public static void main(String[] args) {
        List<String> perms = permutation("", "abcd");

        String[] array = new String[perms.size()];
        for (int i = 0; i < perms.size(); i++) {
            array[i] = perms.get(i);
        }

        int x = array.length;

        for (final String anArray : array) {
            System.out.println(anArray);
        }
    }
}

为排列和组合添加更详细的NcK/NcR

public static void combinationNcK(List<String> inputList, String prefix, int chooseCount, List<String> resultList) {
    if (chooseCount == 0)
        resultList.add(prefix);
    else {
        for (int i = 0; i < inputList.size(); i++)
            combinationNcK(inputList.subList(i + 1, inputList.size()), prefix + "," + inputList.get(i), chooseCount - 1, resultList);

        // Finally print once all combinations are done
        if (prefix.equalsIgnoreCase("")) {
            resultList.stream().map(str -> str.substring(1)).forEach(System.out::println);
        }
    }
}

public static void permNcK(List<String> inputList, int chooseCount, List<String> resultList) {
    for (int count = 0; count < inputList.size(); count++) {
        permNcK(inputList, "", chooseCount, resultList);
        resultList = new ArrayList<String>();
        Collections.rotate(inputList, 1);
        System.out.println("-------------------------");
    }

}

public static void permNcK(List<String> inputList, String prefix, int chooseCount, List<String> resultList) {
    if (chooseCount == 0)
        resultList.add(prefix);
    else {
        for (int i = 0; i < inputList.size(); i++)
            combinationNcK(inputList.subList(i + 1, inputList.size()), prefix + "," + inputList.get(i), chooseCount - 1, resultList);

        // Finally print once all combinations are done
        if (prefix.equalsIgnoreCase("")) {
            resultList.stream().map(str -> str.substring(1)).forEach(System.out::println);
        }
    }
}

public static void main(String[] args) {
    List<String> positions = Arrays.asList(new String[] { "1", "2", "3", "4", "5", "6", "7", "8" });
    List<String> resultList = new ArrayList<String>();
    //combinationNcK(positions, "", 3, resultList);

    permNcK(positions, 3, resultList);

}

这是一个C解:

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>


char* addLetter(char* string, char *c) {
    char* result = malloc(sizeof(string) + 2);
    strcpy(result, string);
    strncat(result, c, 1);
    return result;
}

char* removeLetter(char* string, char *c) {
    char* result = malloc(sizeof(string));
    int j = 0;
    for (int i = 0; i < strlen(string); i++) {
        if (string[i] != *c) {
            result[j++] = string[i];
        }
    }
    result[j] = '\0';

    return result;
}

void makeAnagram(char *anagram, char *letters) {

    if (*letters == '\0') {
        printf("%s\n", anagram);
        return;
    }

    char *c = letters;
    while (*c != '\0') {
        makeAnagram(addLetter(anagram, c),
                    removeLetter(letters, c));
        c++;
    }

}

int main() {

    makeAnagram("", "computer");

    return 0;
}