通过重复生成所有排列
Generating all permutations with repetition
我们如何生成n(给定)个不同的r在任何项可以重复任何次数的情况下的所有可能的排列?
组合学告诉我,它们将有n^r,只是想知道如何用c++/python生成它们?
下面是c++中一个可能的实现,类似于标准库函数std::next_permutation
//---------------------------------------------------------------------------
// Variations with repetition in lexicographic order
// k: length of alphabet (available symbols)
// n: number of places
// The number of possible variations (cardinality) is k^n (it's like counting)
// Sequence elements must be comparable and increaseable (operator<, operator++)
// The elements are associated to values 0÷(k-1), max=k-1
// The iterators are at least bidirectional and point to the type of 'max'
template <class Iter>
bool next_variation(Iter first, Iter last, const typename std::iterator_traits<Iter>::value_type max)
{
if(first == last) return false; // empty sequence (n==0)
Iter i(last); --i; // Point to the rightmost element
// Check if I can just increase it
if(*i < max) { ++(*i); return true; } // Increase this element and return
// Find the rightmost element to increase
while( i != first )
{
*i = 0; // reset the right-hand element
--i; // point to the left adjacent
if(*i < max) { ++(*i); return true; } // Increase this element and return
}
// If here all elements are the maximum symbol (max=k-1), so there are no more variations
//for(i=first; i!=last; ++i) *i = 0; // Should reset to the lowest sequence (0)?
return false;
} // 'next_variation'
这就是用法:
std::vector<int> b(4,0); // four places initialized to symbol 0
do{
for(std::vector<int>::const_iterator ib=b.begin(); ib!=b.end(); ++ib)
{
std::cout << std::to_string(*ib);
}
std::cout << 'n';
}
while( next_variation(b.begin(), b.end(), 2) ); // use just 0-1-2 symbols
将您的排列视为基于n的数字系统中的r位数字。从000开始……
代码很简单
下面是@Inspired方法的一个示例,其中n为字母表的前三个字母,r = 3:
alphabet = [ 'a', 'b', 'c' ]
def symbolic_increment( symbol, alphabet ):
## increment our "symbolic" number by 1
symbol = list(symbol)
## we reverse the symbol to maintain the convention of having the LSD on the "right"
symbol.reverse()
place = 0;
while place < len(symbol):
if (alphabet.index(symbol[place])+1) < len(alphabet):
symbol[place] = alphabet[alphabet.index(symbol[place])+1]
break
else:
symbol[place] = alphabet[0];
place+=1
symbol.reverse()
return ''.join(symbol)
permutations=[]
r=3
start_symbol = alphabet[0] * (r)
temp_symbol = alphabet[0] * (r)
while 1:
## keep incrementing the "symbolic number" until we get back to where we started
permutations.append(temp_symbol)
temp_symbol = symbolic_increment( temp_symbol, alphabet)
if( temp_symbol == start_symbol ): break
你也可以使用itertools:
from itertools import product
r=3
for i in xrange(r-1):
if (i==0):
permutations = list(product(alphabet, alphabet))
else:
permutations = list(product(permutations, alphabet))
permutations = [ ''.join(item) for item in permutations ]
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么不;名字在地图上是按顺序排列的吗
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 找到具有最多子串栅栏的字符串排列
- 重新排列单线以形成闭合多边形?
- 在数组中输入 n 个整数的列表,并以类似于钟摆来回移动的方式排列它们. 输入-1 3 2 5 4,输出5 3 1 2 4
- 输入的 C++ 排列
- 公共/私有/受保护是否会更改内存中结构的排列?
- 如何在 C/C++ 中生成具有 n 组 5 个值(重复项)的所有可能排列的矩阵
- 在向量C++中排列奇数和偶数
- 如何进行排列?
- 矩阵行求和与 RowMajor 和 ColMajor 数据排列的奇怪性能差异
- 在 CPP 中打印具有重复项的选定长度字符的所有排列
- 如何在不使用 C++ 中的数组或函数的情况下查找 N 位数字的所有排列
- 调用参数排列不变函数 f(i++, i++)
- 以 C++ 为单位具有输出限制的排列
- 在C++中寻找排列和组合
- 在 std::map 中重新排列键
- 为什么我得到长度仅为 3 的字符串排列的输出?