有人可以帮我这个:这个程序可以找到任何长度的字符串的所有排列。需要一个非递归形式的相同。 (首选C语言实现)
using namespace std;
string swtch(string topermute, int x, int y)
{
string newstring = topermute;
newstring[x] = newstring[y];
newstring[y] = topermute[x]; //avoids temp variable
return newstring;
}
void permute(string topermute, int place)
{
if(place == topermute.length() - 1)
{
cout<<topermute<<endl;
}
for(int nextchar = place; nextchar < topermute.length(); nextchar++)
{
permute(swtch(topermute, place, nextchar),place+1);
}
}
int main(int argc, char* argv[])
{
if(argc!=2)
{
cout<<"Proper input is 'permute string'";
return 1;
}
permute(argv[1], 0);
return 0;
}
答案 0 :(得分:3)
基于堆栈的非递归等效代码:
#include <iostream>
#include <string>
struct State
{
State (std::string topermute_, int place_, int nextchar_, State* next_ = 0)
: topermute (topermute_)
, place (place_)
, nextchar (nextchar_)
, next (next_)
{
}
std::string topermute;
int place;
int nextchar;
State* next;
};
std::string swtch (std::string topermute, int x, int y)
{
std::string newstring = topermute;
newstring[x] = newstring[y];
newstring[y] = topermute[x]; //avoids temp variable
return newstring;
}
void permute (std::string topermute, int place = 0)
{
// Linked list stack.
State* top = new State (topermute, place, place);
while (top != 0)
{
State* pop = top;
top = pop->next;
if (pop->place == pop->topermute.length () - 1)
{
std::cout << pop->topermute << std::endl;
}
for (int i = pop->place; i < pop->topermute.length (); ++i)
{
top = new State (swtch (pop->topermute, pop->place, i), pop->place + 1, i, top);
}
delete pop;
}
}
int main (int argc, char* argv[])
{
if (argc!=2)
{
std::cout<<"Proper input is 'permute string'";
return 1;
}
else
{
permute (argv[1]);
}
return 0;
}
我试图使它像C一样避免使用c ++ STL容器和成员函数(虽然为了简单起见使用了构造函数)。
注意,排列的生成顺序与原始排列顺序相反。
我应该补充说,以这种方式使用堆栈只是模拟递归。
答案 1 :(得分:3)
另一种方法是分配一个n数组! char数组并以与手工相同的方式填充它们。
如果字符串是“abcd”,则将所有“a”字符放在第一个n-1的位置0!数组,在下一个n-1的位置1!然后将所有“b”字符放在第一个n-2的位置1!数组等,第一个n-3位置2的所有“c”字符!数组等,以及第一个n-4位置3的所有“d”字符!数组等,在每种情况下使用模运算在填充数组时从位置3移动到位置0。
不需要交换,如果你有足够的内存来存储结果,你很早就知道了。
答案 2 :(得分:2)
第一个建议 - 不要按值传递std:string参数。使用const引用
string swtch(const string& topermute, int x, int y)
void permute(const string & topermute, int place)
它将为您节省大量不必要的复制。
对于C ++解决方案,std::next_permutation
标题中包含函数std::prev_permutation
和algorithm
。所以你可以写:
int main(int argc, char* argv[])
{
if(argc!=2)
{
cout<<"Proper input is 'permute string'" << endl;
return 1;
}
std::string copy = argv[1];
// program argument and lexically greater permutations
do
{
std::cout << copy << endl;
}
while (std::next_permutation(copy.begin(), copy.end());
// lexically smaller permutations of argument
std::string copy = argv[1];
while (std::prev_permutation(copy.begin(), copy.end())
{
std::cout << copy << endl;
}
return 0;
}
对于C解决方案,您必须将变量类型从std :: string更改为char *(呃,您必须正确管理内存)。我认为类似的方法 - 编写函数
int next_permutation(char * begin, char * end);
int prev_permutation(char * begin, char * end);
与STL函数具有相同的语义 - 将会这样做。您可以通过解释here找到std::next_permutation
的源代码。我希望你能设法编写一个类似于char *的代码(BTW std :: next_permutation可以使用char *而没有任何问题,但你想要C解决方案)因为我懒得自己做: - )< / p>
答案 3 :(得分:2)
您是否尝试过使用STL?有一个名为next_permutation的算法,给定一个范围将在每次后续调用时返回true,直到遇到所有排列。不仅适用于字符串,也适用于任何“序列”类型。
答案 4 :(得分:1)
这解决了没有递归的问题。唯一的问题是,如果字符串在字符串中重复出现,它将生成重复的输出。
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
int factorial(int n)
{
int fact=1;
for(int i=2;i<=n;i++)
fact*=i;
return fact;
}
char *str;
void swap(int i,int j)
{
char temp=str[i];
str[i]=str[j];
str[j]=temp;
}
void main()
{
clrscr();
int len,fact,count=1;
cout<<"Enter the string:";
gets(str);
len=strlen(str);
fact=factorial(len);
for(int i=0;i<fact;i++)
{
int j=i%(len-1);
swap(j,j+1);
cout<<"\n"<<count++<<". ";
for(int k=0;k<len;k++)
cout<<str[k];
}
getch();
}
答案 5 :(得分:0)
#include <iostream>
#include <string>
using namespace std;
void permuteString(string& str, int i)
{
for (int j = 0; j < i; j++) {
swap(str[j], str[j+1]);
cout << str << endl;
}
}
int factorial(int n)
{
if (n != 1) return n*factorial(n-1);
}
int main()
{
string str;
cout << "Enter string: ";
cin >> str;
cout << str.length() << endl;
int fact = factorial(str.length());
int a = fact/((str.length()-1));
for (int i = 0; i < a; i++) {
permuteString(str, (str.length()-1));
}
}