Language agnostic 如何在给定长度内求k的置换?

Language agnostic 如何在给定长度内求k的置换?,language-agnostic,permutation,Language Agnostic,Permutation,如何在给定的长度内找到k的置换 例如: 单词cat有3个字母:我如何找到单词cat中2的所有排列。 结果应该是:ac,at,ca,ac,等等 这不是家庭作业问题。 可以使用任何语言,但更可取的是:C/C++或C#。 我知道如何为大小长度创建递归,但不为自定义大小创建递归。递归解决方案有什么问题,并传递一个额外的参数(深度),以便递归函数立即返回深度>n。不是最有效的,但它可以工作: public class permutation { public static List<str

如何在给定的长度内找到k的置换

例如:

单词
cat
有3个字母:我如何找到单词
cat
中2的所有排列。 结果应该是:
ac
at
ca
ac
,等等


这不是家庭作业问题。 可以使用任何语言,但更可取的是:C/C++或C#。
我知道如何为大小长度创建递归,但不为自定义大小创建递归。

递归解决方案有什么问题,并传递一个额外的参数(深度),以便递归函数立即返回深度>n。

不是最有效的,但它可以工作:

public class permutation
{
    public static List<string> getPermutations(int n, string word)
    {
        List<string> tmpPermutation = new List<string>();
        if (string.IsNullOrEmpty(word) || n <= 0)
        {
            tmpPermutation.Add("");
        }
        else
        {
            for (int i = 0; i < word.Length; i++)
            {
                string tmpWord = word.Remove(i, 1);
                foreach (var item in getPermutations(n - 1, tmpWord))
                {
                    tmpPermutation.Add(word[i] + item);
                }
            }
        }
        return tmpPermutation;
    }
}
公共类置换
{
公共静态列表getPermutations(int n,字符串字)
{
List=new List();
如果(string.IsNullOrEmpty(word)| | n这里有一个C#中的字符,它甚至可以用于重复字符。例如,对于长度为2的排列,它给出:

英国广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司广播公司

基本思想是固定第一个字符,然后形成所有长度为k-1的排列,然后将字符前置到那些k-1长度的排列。为了处理重复字符,我们跟踪剩余的计数(即可用于子排列的字符)

不是典型的代码,但应该给你的想法。(如果你发现错误,让我知道,我可以编辑)

静态列表排列(字典输入,整数长度){
列表排列=新列表();
列表字符=新列表(输入.Keys);
//基本情况。
如果(长度==0){
置换.Add(string.Empty);
返回置换;
}
foreach(字符中的字符c){
//还有此角色的实例可供使用。
如果(输入[c]>0){
//使用一个实例。
输入[c]-;
//查找长度为-1的子置换。
列表子项=排列(输入,长度-1);
//返回实例。
输入[c]++;
foreach(子项中的字符串s){
//将字符前置为第一个字符。
添加(s.Insert(0,新字符串(c,1));
}
}
}
返回置换;
}
这是我的完整程序,可以使用它:

using System;
using System.Collections.Generic;

namespace StackOverflow {

    class Program {
        static void Main(string[] args) {
            List<string> p = Permutations("abracadabra", 3);
            foreach (string s in p) {
                Console.WriteLine(s);
            }
        }

        static List<string> Permutations(string s, int length) {
            Dictionary<char, int> input = new Dictionary<char, int>();
            foreach (char c in s) {
                if (input.ContainsKey(c)) {
                    input[c]++;
                } else {
                    input[c] = 1;
                }
            }
            return Permutations(input, length);
        }

        static List<string> Permutations(Dictionary<char, int> input, 
                                                          int length) {
            List<string> permutations = new List<string>();

            List<char> chars = new List<char>(input.Keys);
            if (length == 0) {
                permutations.Add(string.Empty);
                return permutations;
            }

            foreach (char c in chars) {
                if (input[c] > 0) {
                    input[c]--;
                    List<string> subpermutations = Permutations(input, 
                                                                length - 1);
                    input[c]++;

                    foreach (string s in subpermutations) {
                        permutations.Add(s.Insert(0,new string(c,1)));
                    }
                }
            }

            return permutations;
        }
    }
}
使用系统;
使用System.Collections.Generic;
命名空间堆栈溢出{
班级计划{
静态void Main(字符串[]参数){
列表p=排列(“abracadabra”,3);
foreach(p中的字符串s){
控制台。写入线(s);
}
}
静态列表置换(字符串s,整数长度){
字典输入=新字典();
foreach(字符c在s中){
if(输入。ContainsKey(c)){
输入[c]++;
}否则{
输入[c]=1;
}
}
返回置换(输入、长度);
}
静态列表排列(字典输入,
整数长度){
列表排列=新列表();
列表字符=新列表(输入.Keys);
如果(长度==0){
置换.Add(string.Empty);
返回置换;
}
foreach(字符中的字符c){
如果(输入[c]>0){
输入[c]-;
列表子项=排列(输入,
长度-1);
输入[c]++;
foreach(子项中的字符串s){
添加(s.Insert(0,新字符串(c,1));
}
}
}
返回置换;
}
}
}

如果我没有弄错的话,这个问题也可以通过combinadics解决,因为在上,也有参考实现

我自己使用Java解决方案()从一个数字序列生成所有可能的三元组,这应该没有什么不同


我缺乏必要的资金来解释其背后的数学原理,但据我所知,这是迭代集合中所有可能的nCr(例如,对于您的cat示例为3C2)选择的最简单的方法。

首先找到数组的可能子集。您可以在 这是一种递归方法,在

然后用STL算法计算每个子集的排列

我还没有实现它,但我认为它应该可以工作。

void Prem(char*str,int k,int length){
void Prem (char *str, int k, int length) {
    if (k == length-1){
         printf("%s\n",str);
         return;
    } else {
        for (int i = k ; i < length; ++i) {
            char t = str[k];
            str[k] = str[i];
            str[i] = t;
            Prem(str,k+1,length);
            t = str[k];
            str[k] = str[i];
            str[i] = t;
        }
    }
}
如果(k==长度-1){ printf(“%s\n”,str); 返回; }否则{ 对于(int i=k;i
任何特定语言?听起来像是家庭作业问题。不……不是家庭作业问题,任何语言都可以使用,但更可取的是:C/C++或C#。我知道如何为大小长度创建递归,但不为自定义大小创建递归。@KennyTM:不。这不是我的意思。因为他似乎想要英语单词,香蕉是有效的输入,所以你应该这样做现在输出中没有重复aa(标准算法会重复)。@Y_-Y:很高兴它有帮助!很高兴在很长时间后再次访问这个。
void Prem (char *str, int k, int length) {
    if (k == length-1){
         printf("%s\n",str);
         return;
    } else {
        for (int i = k ; i < length; ++i) {
            char t = str[k];
            str[k] = str[i];
            str[i] = t;
            Prem(str,k+1,length);
            t = str[k];
            str[k] = str[i];
            str[i] = t;
        }
    }
}