在CPP中重复的n个字符的长度为k的所有排列

时间:2016-03-10 11:18:17

标签: c++ permutation

我想知道CPP中是否已经有一个实现来查找重复长度为k(1,2,3,4等)的n个字符的所有排列。我希望有,但我找不到。

例如,如果string= (A,B,C,D)我希望查找string的重复长度为k =2的所有排列。

输出类似于:

AA
AB
AC
AD
.
.
.
DD

总排列数为16.

4 个答案:

答案 0 :(得分:3)

简单的递归解决方案,肯定会对你有用。

让我先重新编写您的规范:重复字符打印所有排列

  

给定一个长度为n的字符串,打印给定字符串的所有排列。   允许重复使用字符

对于大小为n的给定字符串,将有n ^ k个可能的长度为" length"的字符串。我们的想法是从一个空输出字符串开始(我们在下面的代码中将其称为前缀)。逐个添加所有字符到前缀。对于添加的每个字符,通过递归调用" length"来打印具有当前前缀的所有可能字符串。等于"长度" -1。

#include <string>
#include <iostream>


void print_str(const char*,std::string,const int, const int);

int main()

{

    int lenght = 2;

    char str[] = {'A', 'B', 'C', 'D'};



    int n = sizeof str;

    print_str(str, "", n, lenght);  //Note: this function works on all cases and not just the case above

    return 0;

}

// The main recursive method to print all possible strings of length "length"
    void print_str(const char str[],std::string prefix,const int n, const int lenght)

    {

        if (lenght == 1)

            {

                for (int j = 0; j < n; j++)

                std::cout << prefix + str[j] << std::endl;

            }//Base case: lenght = 1, print the string "lenght" times + the remaining letter

        else

            {


               // One by one add all characters from "str" and recursively call for "lenght" equals to "lenght"-1
                for (int i = 0; i < n; i++)

                // Next character of input added
                print_str(str, prefix + str[i], n, lenght - 1);
                // "lenght" is decreased, because we have added a new character

            }

    }

以下是上述代码的执行:

enter image description here

<强>参考文献:

http://www.geeksforgeeks.org/print-all-permutations-with-repetition-of-characters/

http://www.geeksforgeeks.org/print-all-combinations-of-given-length/

更新:此更新正在回复以下规范。

  

我还需要一个帮助!!因为我是CPP编程的新手。假设是   length = 3我怎样才能让它从所有排列开始   长度= 1到长度= 3在一个数组中。获得所有的手段   长度= 1,长度= 2和长度= 3的排列一起存储在   数组

#include <string>
#include <iostream>
#include <vector>

void print_str(const char*,std::string,const int, const int);
std::vector<std::string> permutations ;  // the vector permutations which will hold all the permutations, 
                                       //if you want you can use it for later use or you can use the array below which is nothing than a copy of this vector.

int NumberOfPermutations = 0; // this variable holds the number of permutations 



int main()

{

    int lenght = 3;

    char str[] = {'A', 'B', 'C', 'D'};

    int n = sizeof str;
//here we loop through all the possible lenghts 1, 2 and 3
    for (int k = 1; k <= lenght; k++)

               {

                   print_str(str, "", n, k);  //Note: this function works on all cases and not just the case above
                }


    std::string* permut_array =  new std::string[NumberOfPermutations]; // the array that we will use to store the permutations in

    std::copy(permutations.begin(), permutations.end(), permut_array); // here we copy the vector into the array 

    //if you want you can use your array to print the permutation as folow

    for (int k = 0; k < NumberOfPermutations; k++)

               {

                   std::cout << permut_array[k] << std::endl;
                }

    return 0;

}

// The main recursive method to print all possible strings of length "length"
    void print_str(const char str[],std::string prefix,const int n, const int lenght)

    {

        if (lenght == 1)

            {

                for (int j = 0; j < n; j++)

               {
                   // i commented this ligne so that if you want to use your array to print your permutations you will not get a screnn with permutations printed 2 times
                   //std::cout << prefix + str[j] << std::endl; 
                   permutations.push_back(prefix + str[j]); // the vector that we will use to store the permutations in
                }

            }//Base case: lenght = 1, print the string "lenght" times + the remaining letter

        else

            {


               // One by one add all characters from "str" and recursively call for "lenght" equals to "lenght"-1
                for (int i = 0; i < n; i++)

                // Next character of input added
                 print_str(str, prefix + str[i], n, lenght - 1);
                // "lenght" is decreased, because we have added a new character

            }
        NumberOfPermutations = permutations.size();
    }

答案 1 :(得分:2)

这不是一种排列,这可能解释了为什么你找不到答案。

您实际要问的是如何使用数字0..k-1在基本 n 中打印数字A,B,C,D。我会用熟悉的数字0,1,2,3重写你的例子:

00
01
02
03
10
11
12
13
..
33

没有标准的C ++方法,但现在您知道它的名称,网上有大量的代码。或者只是自己写。提示:i的最后一位数值为i % n

答案 2 :(得分:1)

你可以使用std::next_permutation()作为πάνταῥεῖ说,但既然你想用重复来定义长度和字符,你可以做一些容易实现的事情,如:

    std::string s = "aabbccdd";
    std::set<std::string> string_set;
    std::sort(s.begin(), s.end());
    do {
        string_set.insert(s.substr(0, 2));
    } while(std::next_permutation(s.begin(), s.end()));
    for(auto i = string_set.begin(); i != string_set.end(); ++i)
        std::cout << *i << std::endl;

答案 3 :(得分:0)

此解决方案适用于所有标准容器以及静态数组。我认为这也可以用于类和结构

#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <list>
#include <iterator>

template<typename InputIt, typename T>
bool nextPermutationWithRepetition(InputIt begin, InputIt end, T from_value, T to_value) {
    auto it = std::find_if_not(std::make_reverse_iterator(end),
                               std::make_reverse_iterator(begin),
                               [&to_value](auto current) { return to_value == current; });

    if (it == std::make_reverse_iterator(begin))
        return false;

    auto bound_element_iterator = std::prev(it.base());

    (*bound_element_iterator)++;
    std::fill(std::next(bound_element_iterator), end, from_value);

    return true;
}

int main() {
    std::list<int> vec(3, 0);

    do {
        std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
        std::cout << std::endl;
    } while (nextPermutationWithRepetition(vec.begin(), vec.end(), 0, 2));

    return  0;
}