我上周问了一个关于C ++中排列的问题(List of combinations of N balls in M boxes in C++)。
答案对我帮助很大,但我的问题现在已经改变了。 我想要做的是从这个python函数到C ++的转换,在结果中保持相同的顺序:
def combinations_with_replacement_counts(n, r): #(n-boxes, r-balls)
size = n + r - 1
for indices in itertools.combinations(range(size), n-1):
#print indices
starts = [0] + [index+1 for index in indices]
stops = indices + (size,)
yield tuple(map(operator.sub, stops, starts))
我没有蟒蛇的技能,尽管我阅读了文档,但我不明白这个功能。
答案 0 :(得分:3)
你知道python是解释的,对吗?你可以直接在python中输入你不理解的行,看看会发生什么......首先从小值开始。
我不理解itertools.combinations()算法
文档为here,包含示例输出。
请注意,combinations
返回的值是惰性的,因此您需要强制进行评估才能看到它:
>>> import itertools
>>> itertools.combinations(range(4), 2)
<itertools.combinations object at 0x979a964>
>>> list(itertools.combinations(range(4), 2))
[(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]
现在combinations
做了什么?如果没有,请玩它。
...和“stops = indices +(size,)”
的语法
所以尝试它,它不会咬人:
>>> indices=list(itertools.combinations(range(4), 2))[0]
>>> size=4
>>> stops=indices + (size,)
>>> indices
(0, 1)
>>> stops
(0, 1, 4)
语法(x,)
创建一个单元素元组(一个不变的序列 - 就像list
一样,你不能改变但是用圆括号()
而不是方括号{{1} }})。您可以使用[]
创建单元素列表,但[x]
不明确,因为圆括号也用于其他事情,如函数参数和分组。
关于map(),...
阅读doc,玩一下,这并不难。
答案 1 :(得分:2)
这个C ++代码似乎与你的python示例具有相同的结果。它远非完美的,你仍然可以理解算法甚至使用这个实现。
#include <deque>
typedef std::deque<size_t> BoxList;
class Generator {
size_t boxNum, ballNum, ownBox;
Generator* recursive;
public:
~Generator() { if ( recursive == NULL ) delete recursive; }
Generator( size_t boxes, size_t balls ) : boxNum(boxes), ballNum(balls) {
if ( boxes > 1 ) {
recursive = new Generator( boxes-1, balls );
ownBox = 0;
} else {
recursive = NULL;
ownBox = balls;
}
}
BoxList operator()() {
if ( ownBox > ballNum ) throw 1;
if ( boxNum <= 1 ) return BoxList( 1, ownBox++ );
try {
BoxList res = recursive->operator()();
res.push_front( ownBox );
return res;
}
catch(...) {
delete recursive;
ownBox++;
recursive = new Generator( boxNum-1, ballNum-ownBox );
return operator()();
}
}
};
类接口允许您将其用作标准生成器。当已经迭代了所有可能的选项时,Operator()将生成异常。
Generator g( boxes, balls );
try{
while( true )
g();
}
catch(...) {}
答案 2 :(得分:0)
你引用的Python代码正在实现我在my answer to your question中描述的算法:它正在迭代放置 r 的可能方法 - 在 n +中的1个框 r - 1个位置,然后列出相邻位置之间的差异(计算扫入该方框的球数)。