使用python我必须使用python获取给定子集的所有排列。 我使用了itertools.permutation,但结果有点不同。
想想一台机器,它有最大的容量,我们的产品可以一起生产,我们必须填补机器的容量。
输出格式并不重要,我用字典来描述它。我会在得到这些组合后进行计算。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct charact {
char ch;
int occurs;
struct charact *next;
};
typedef struct charact Char;
typedef Char * ListofChar;
typedef Char * CharNode_ptr;
void letters(char name[50], ListofChar * chars_ptr);
void report(ListofChar chars);
Char * createnode(char ch);
int main() {
char name[50];
ListofChar chars = NULL;
scanf("%s", name);
letters(name,&chars);
report(chars);
return 0;
}
Char * createnode(char ch) {
CharNode_ptr newnode_ptr ;
newnode_ptr = malloc(sizeof (Char));
newnode_ptr -> ch = ch;
newnode_ptr -> occurs = 0;
newnode_ptr -> next = NULL;
return newnode_ptr;
}
void letters(char name[50],ListofChar* lst_ptr){
ListofChar newnode ;
newnode =(Char*)malloc(sizeof(Char));
if(!newnode){printf("adinamia mnimis");}
int i,j;
for( i = 0 ; i < strlen(name) ; i++){
newnode->ch = name[i] ;
printf("Look: %c\n",newnode->ch);
newnode->next = *lst_ptr ;
*lst_ptr = newnode ;
}
for( i = 0 ; i < 50 ; i++){
for( j = 0 ; j < strlen(name) ; j++){
if (newnode->ch == name[i]){
newnode->occurs++;
printf("uhm : %c\n",newnode->ch) ;
newnode = newnode->next;
break;
}
printf("hey : %c\n",newnode->ch);
}
}
}
void report(ListofChar chars) {
ListofChar current ;
current = chars ;
printf("the occurences of each letter are:\n");
while(current != NULL){
printf("%c : %d\n", current->ch,current->occurs );
current = current->next ;
}
if(current==NULL)printf("fail");
return;
}
我们不想要重复元素:
products = {'x','y','z','a'}
machine_capcacity = 8
#required output as follows:
{'x':5,'y':1,'z':1,'a':1}
{'x':4,'y':2,'z':1,'a':1}
{'x':4,'y':1,'z':2,'a':1}
{'x':4,'y':1,'z':1,'a':2}
{'x':3,'y':3,'z':1,'a':1}
{'x':3,'y':1,'z':3,'a':1}
{'x':3,'y':1,'z':1,'a':3}
{'x':3,'y':2,'z':2,'a':1}
{'x':3,'y':2,'z':1,'a':2}
{'x':3,'y':1,'z':2,'a':2}
{'x':2,'y':4,'z':1,'a':1}
# ...
{'x':6,'y':1,'z':1} # This can't be in results,since need at least 1 element of product
{'x':4,'y':1,'z':1,'a':1} # This can't be in results,since we need to fill the capacity
和
{'x':5,'y':1,'z':1,'a':1}
对我们来说是一回事。
答案 0 :(得分:1)
您可以使用递归函数查找range(machine_capacity)
中值的所有可能组合,这两种值的总和为8
并且是唯一的。然后,products
中的元素可以映射到找到的组合的子列表中的每个元素:
products = ['x','y','z','a']
machine_capacity = 8
def combinations(d, current = []):
if len(current) == len(products):
yield current
else:
for i in range(machine_capacity):
if sum(current+[i]) <= machine_capacity:
yield from combinations(d, current+[i])
data = [dict(zip(products, i)) for i in filter(lambda x:sum(x) == 8 and len(x) == len(set(x)), combinations(machine_capacity))]
输出:
[{'a': 5, 'x': 0, 'z': 2, 'y': 1}, {'a': 4, 'x': 0, 'z': 3, 'y': 1}, {'a': 3, 'x': 0, 'z': 4, 'y': 1}, {'a': 2, 'x': 0, 'z': 5, 'y': 1}, {'a': 5, 'x': 0, 'z': 1, 'y': 2}, {'a': 1, 'x': 0, 'z': 5, 'y': 2}, {'a': 4, 'x': 0, 'z': 1, 'y': 3}, {'a': 1, 'x': 0, 'z': 4, 'y': 3}, {'a': 3, 'x': 0, 'z': 1, 'y': 4}, {'a': 1, 'x': 0, 'z': 3, 'y': 4}, {'a': 2, 'x': 0, 'z': 1, 'y': 5}, {'a': 1, 'x': 0, 'z': 2, 'y': 5}, {'a': 5, 'x': 1, 'z': 2, 'y': 0}, {'a': 4, 'x': 1, 'z': 3, 'y': 0}, {'a': 3, 'x': 1, 'z': 4, 'y': 0}, {'a': 2, 'x': 1, 'z': 5, 'y': 0}, {'a': 5, 'x': 1, 'z': 0, 'y': 2}, {'a': 0, 'x': 1, 'z': 5, 'y': 2}, {'a': 4, 'x': 1, 'z': 0, 'y': 3}, {'a': 0, 'x': 1, 'z': 4, 'y': 3}, {'a': 3, 'x': 1, 'z': 0, 'y': 4}, {'a': 0, 'x': 1, 'z': 3, 'y': 4}, {'a': 2, 'x': 1, 'z': 0, 'y': 5}, {'a': 0, 'x': 1, 'z': 2, 'y': 5}, {'a': 5, 'x': 2, 'z': 1, 'y': 0}, {'a': 1, 'x': 2, 'z': 5, 'y': 0}, {'a': 5, 'x': 2, 'z': 0, 'y': 1}, {'a': 0, 'x': 2, 'z': 5, 'y': 1}, {'a': 1, 'x': 2, 'z': 0, 'y': 5}, {'a': 0, 'x': 2, 'z': 1, 'y': 5}, {'a': 4, 'x': 3, 'z': 1, 'y': 0}, {'a': 1, 'x': 3, 'z': 4, 'y': 0}, {'a': 4, 'x': 3, 'z': 0, 'y': 1}, {'a': 0, 'x': 3, 'z': 4, 'y': 1}, {'a': 1, 'x': 3, 'z': 0, 'y': 4}, {'a': 0, 'x': 3, 'z': 1, 'y': 4}, {'a': 3, 'x': 4, 'z': 1, 'y': 0}, {'a': 1, 'x': 4, 'z': 3, 'y': 0}, {'a': 3, 'x': 4, 'z': 0, 'y': 1}, {'a': 0, 'x': 4, 'z': 3, 'y': 1}, {'a': 1, 'x': 4, 'z': 0, 'y': 3}, {'a': 0, 'x': 4, 'z': 1, 'y': 3}, {'a': 2, 'x': 5, 'z': 1, 'y': 0}, {'a': 1, 'x': 5, 'z': 2, 'y': 0}, {'a': 2, 'x': 5, 'z': 0, 'y': 1}, {'a': 0, 'x': 5, 'z': 2, 'y': 1}, {'a': 1, 'x': 5, 'z': 0, 'y': 2}, {'a': 0, 'x': 5, 'z': 1, 'y': 2}]
答案 1 :(得分:1)
这是一个不依赖于itertools
的解决方案,因为它会受到所有限制(一种产品产生独特结果且每种产品至少出现一次)的设计:
products = {'x','y','z','a'}
machine_capacity=8
def genCap(capacity = machine_capacity,used = 0):
if used == len(products)-1: yield capacity,None
else:
for i in range(1,2+capacity-len(products)+used):
yield i,genCap(capacity-i,used+1)
def printCaps(caps,current = []):
if caps is None:
print(dict(zip(products,current)))
return
for i in caps:
printCaps(i[1],current+[i[0]])
printCaps(genCap())
可以通过尾递归等进行优化。看起来几乎像groupby
,但我看不到使用它的简单方法。
对于后代我留下了旧的解决方案 - 产品重复计数,因此过滤它会成为它自己的问题:
你把产品与排列混淆了。以下是使用itertools
产品的快速解决方案,以及Counter
集合来创建所需的输出:
from collections import Counter
from itertools import product
products = {'x','y','z','a'}
machine_capacity=8
for x in filter(lambda x: len(x) == len(products),
map(Counter,product(products,repeat=machine_capacity))):
print(dict(x))
请注意,product
和map
都是懒惰的,因此在您需要之前不会对其进行评估。 Counter
提供您想要的输出,并转换为dict
进行清理。注意在任何地方都不保证订单。 filter
用于确保您的所有产品至少出现一次(计数器的长度等于产品的长度) - 并且它也是惰性的,因此仅在您需要时进行评估。