比如我有一个"abc" 那么全排列就是 abc acb bac bca cab cba,
如果是“aac”,那么就是 aac aca caa,而不是 aac aca aac aca caa caa.
递归:从左往右的模型。
C++: vector
void process(vector<char> set, string path, vector<string>& ans)
{
if (set.empty()) //集合为什么是空 所有的字符都选完了
{
ans.push_back(path);
return;
}
unordered_set<char> picks ; //当前挑过的字符,set不是已经去重过了嘛
//set所有字符都可以作为当前字符,但一旦做了当前的,后面就能要这个字符了
for (int index = 0; index < set.size(); index++)
{
if (!picks.count(set.at(index))) //当前字符是没有挑过的
{
picks.insert(set.at(index));
string pick = path + set.at(index); //pick 选中的 =前面选的+当前字符set.get(index)
//选过的就不能用了,要删掉。删掉分两步:拷贝出来,然后删掉
//next是去掉了当前字符的集合,内存地址是不一样的。
vector<char> next; //先拷贝一下 内存地址不一样
next.assign(set.begin(), set.end());
auto del= next.begin()+index;
next.erase(del); //去掉当前字符
process(next, pick, ans);
}
}
}
//调用函数 输入就是string
//递归函数
vector<string>* printAllC(string str)
{
vector<string>* ans = new vector<string>(); //1.输出:先生成ANS
vector <char> set ; //2输入:string中每个字符放到集合里去 list结构
for(int i=0;i<str.length();i++)
{
set.push_back(str[i]);
}
for (int i = 0; i < set.size(); i++)
{
cout << set[i] << ",";
}
process(set, "", *ans); //0开始做决定
return ans;
}
//1.全排列,但不能出现重复的
void printAllC_main()
{
cout << "************main_printAllC****************" << endl;
string test = "aac";
vector<string> *ans = printAllC(test);
for (auto it = ans->begin(); it != ans->end(); it++)
{
cout << *it << endl;
}
}