我发现其他类似的问题太复杂了。
我认为这意味着如果我们获得底池,那么组合将是 锅 选择 最佳 锅 PTO 锅
所以我写了下面的代码:
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char s[10];
char temp;
cin>>s;
char t[10];
for(int i=0;i<3;i++)
{
for(int j=i;j<3;j++)
{
strcpy(t,s);
temp=s[i];
s[i]=s[j];
s[j]=temp;
cout<<s<<"\n";
strcpy(s,t);
}
}
有更好的方法吗?
答案 0 :(得分:4)
这个问题本质上是O(N!)(阶乘)复杂性问题。原因在于,对于每个潜在单词的每个位置,可以填充该位置的字符的可能性递减,例如,有4个字母a,b,c和d。
-----------------
Positions: | 0 | 1 | 2 | 3 |
-----------------
In position 0, there are 4 possibilities, a, b, c, or d
Lets fill with a
-----------------
String: | a | | | |
-----------------
Now Position 1 has 3 possibilities of fill letters b, c, or d
Lets fill with b
-----------------
String: | a | b | | |
-----------------
Now Position 2 has 2 possibilities of fill letters c, or d
Lets fill with c
-----------------
String: | a | b | c | |
-----------------
Now Position 1 has only 1 possibility for a fill letter: d
-----------------
String: | a | b | c | d |
-----------------
这仅适用于1个字符串,复杂性来自(在这种情况下)可以填充给定输出字的字符位置的潜在可能性,因此:
4 * 3 * 2 * 1 = 4!
这可以扩展到任意数量的输入字母,正好是N!如果没有重复的字母。这也代表了你应该得到的数量。
执行此类操作的代码可以是(在C中测试和工作):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
void printPermutations(int level, const char * inString, char * outString){
unsigned int len = strlen(inString);
char * unusedLetter;
int j;
if( 1 == len ){
printf("%s%s\n", outString, inString);
}else{
unusedLetters = (char *)malloc(sizeof(char) * (len - 1));
for(int startLetter = 0; startLetter < len; startLetter++){
outString[level] = inString[startLetter];
// setup the "rest of string" string
j = 0;
for(int i = 0; i < len; i++){
if( i != startLetter ){
unusedLetter[j] = inString[i];
j++;
}
}
// recursive call to THIS routine
printPermutations(level+1, unusedLetters, outString);
}
}
}
int main(int argc, char * argv[]){
unsigned int len;
char * outString;
if(argc != 2) return 0;
len = strlen(argv[1]);
outString = (char *)malloc(sizeof(char) * (len + 1));
outstring[len] = '\0';
printPermutations(0, argv[1], outString);
return 0;
}
从外面打电话,如下:
projectName abc
使用“abc”
输出样本abc
acb
bac
bca
cab
cba
如果有重复的字母,请说a,a,b,c
那么总会有重复的话。
对于这些情况,UNIQUE结果词的数量应该是因子的唯一字符数量,因此对于上述情况,它将是3!不是4!。
这样做的原因是a填充给定点并不重要,因此给出的唯一性是提供的唯一字母数量。这也是一个难题,我会说你应该生成所有N!首先是单词,然后运行第二个算法来搜索重复单词并删除。可能有更聪明的方法可以动态生成独特的单词。
答案 1 :(得分:3)
以下解决方案是O(N!)。这也需要重复考虑:
#include<stdio.h>
void permute(char s[10],char *p);
int count=0;
main(){
char s[10];
int i;
scanf("%s",s);
permute(s,s);
}
//takes into account repetetion
void permute(char s[10],char *p){
char *swap,temp;
if(*(p+1)==0) {
count++;
printf("%4d] %s\n",count,s);
}
else{
for(swap=p;*swap;++swap){
char *same;
for(same=p;*same!=*swap;++same){};
if(same==swap){
temp=*swap;
*swap=*p;
*p=temp;
permute(s,p+1);
*p=*swap;/*restoring the original string*/
*swap=temp;
}
}
}
}