Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;字符串的递归置换算法->;不跳过重复项_C++_String_Recursion_Permutation - Fatal编程技术网

C++ C++;字符串的递归置换算法->;不跳过重复项

C++ C++;字符串的递归置换算法->;不跳过重复项,c++,string,recursion,permutation,C++,String,Recursion,Permutation,我很难找到一个简单的语句来跳过这个递归置换代码的重复项。我到处都找过,似乎只找到使用swap或java的例子。从我收集的信息来看,我想我需要在for循环后面加一条线 谢谢大家! #include "genlib.h" #include "simpio.h" #include <string> #include <iostream> void ListPermutations(string prefix, string rest); int main() {

我很难找到一个简单的语句来跳过这个递归置换代码的重复项。我到处都找过,似乎只找到使用swap或java的例子。从我收集的信息来看,我想我需要在for循环后面加一条线

谢谢大家!

#include "genlib.h"
#include "simpio.h"
#include <string>
#include <iostream>

void ListPermutations(string prefix, string rest);


int main() {

    cout << "Enter some letters to list permutations: ";
    string str = GetLine();
    cout << endl << "The permutations are: " << endl;
    ListPermutations("", str);

    return 0;
}

void ListPermutations(string prefix, string rest)
{
    if (rest == "") 
    {
        cout << prefix << endl;
    } 
    else 
    {   
        for (int i = 0; i < rest.length(); i++) 
        {
            if (prefix != "" && !prefix[i]) continue; // <--- I tried adding this, but it doesn't work
            cout << endl<< "prefix: " << prefix << " | rest: " << rest << endl;     
            string newPrefix = prefix + rest[i];
            string newRest = rest.substr(0, i) + rest.substr(i+1);  
            ListPermutations(newPrefix, newRest);           
        }    
    }
}
#包括“genlib.h”
#包括“simpio.h”
#包括
#包括
无效列表置换(字符串前缀、字符串剩余);
int main(){

C++中的CUT< P>生成置换使用< /P>
它可以很好地处理重复条目,并且做正确的事情

忽略std::next_排列的可用性,因为您对上一个答案的评论

如果你想生成所有唯一的排列,你需要在某个时刻将它们排列整齐。最简单的方法是将它们全部放在一个向量中,排序,然后在打印出来时抑制重复的相邻条目。但这比需要的慢得多

您需要首先对字符串进行排序,以便在每个字符串之后生成相同的排列。然后在for循环中,确保跳过“rest”中的任何重复字母。类似于:

    char lastAdditionToPrefix = '\0';
    for (int i = 0; i < rest.length(); i++) 
    {
        if (rest[i] == lastAdditionToPrefix) continue;
        lastAdditionToPrefix = rest[i];
        cout << endl<< "prefix: " << prefix << " | rest: " << rest << endl;     
        ...
char lastAdditionToPrefix='\0';
for(int i=0;i
void ListPermutations(string prefix, string rest)
{
if (rest == "") 
{
    cout << prefix << endl;
} 
else 
{   
    for (int i = 0; i < rest.length(); i++) 
    {


        //test if rest[i] is unique.
        bool found = false;
        for (int j = 0; j < i; j++) 
        {
            if (rest[j] == rest[i])
                found = true;
        }
        if(found)
            continue;
        string newPrefix = prefix + rest[i];
        string newRest = rest.substr(0, i) + rest.substr(i+1);  
        ListPermutations(newPrefix, newRest);           
    }    
}
}
无效列表置换(字符串前缀、字符串剩余)
{
如果(rest==“”)
{

cout经过测试,工作正常。其思想是,对于每个堆栈级别,在位置i,记住字符是否已经在该位置

using namespace std;

void doPermutation(vector<char> &input, int index) {
    bool used[26] = {false};

    if(index == input.size()) {
        copy(input.begin(), input.end(), ostream_iterator<char>(cout, "") );
        cout << endl;

    } else {
      int i, j;
      for(i =index; i < input.size(); i++ ) {
        if(used[ input[i]-'a'] == false) {
           swap(input[i], input[index]);
           doPermutation(input, index+1);
           swap(input[i], input[index]);
           used[input[i]-'a'] = true;
       } 
      }
    }
}

  void permutation(vector<char>& input) {
      doPermutation(input, 0);
  }


int main()
{
   cout << "Hello World" << endl; 
   const char* inp = "alla";
   vector<char> input(inp, inp + 4 );

   permutation(input);

   return 0;
}
使用名称空间std;
void doPermutation(向量和输入,整数索引){
布尔使用[26]={false};
if(index==input.size()){
复制(input.begin()、input.end()、ostream_迭代器(cout,“”);

cout有无重复的算法的不同之处在于,在交换字符时,请确保您要交换的字符以前没有交换过。使用哈希映射跟踪您以前交换过的字符

请参见下面的C代码

    private void PermuteUniqueHelper(int[] nums, int index, List<IList<int>> res)
    {
        var used = new Dictionary<int, bool>();
        if (index == nums.Length)
        {
            res.Add(new List<int>(nums));
            return;
        }

        for (int i = index; i < nums.Length; i++)
        {
            if (!used.ContainsKey(nums[i]))
            {
                swap(nums[i], nums[index]);

                this.PermuteUniqueHelper(nums, index + 1, res);

                swap(nums[i], nums[index]);

                used.Add(nums[i], true);
            }
        }
    }
private void PermuteUniqueHelper(int[]nums,int index,List res)
{
var used=newdictionary();
如果(索引==nums.Length)
{
决议添加(新列表(nums));
返回;
}
for(int i=索引;i
谢谢,但是是否有其他方法使用布尔逻辑或其他方法?谢谢,很抱歉没有提前指定作业。要跳过重复项,您可能必须修改代码以保持每个字符及其当前计数。递归函数将使用一个字符并降低其计数并调用自身。我强烈感觉到你可以用这样的方式生成它们,这样副本就不会在第一时间被释放出来。然而,我的大脑现在在马尔芬蒂诺上,我似乎无法正确地想象它now@sehe-见下面我的答案-您只需要在开始之前调用str上的sort,并且对于rest中的每个唯一字符只递归一次。排序甚至可能不正确必要的…但我现在还不能确定如果没有它它是否能工作谢谢,vector确实会慢一些。我的感觉是它与比较前缀和rest有关,并跳过下一个递归或增量I?当我试图解决它时,我的大脑会爆炸…我认为你不需要在一个时间比较前缀和restll-您只需要确保您的函数对“rest”中的每个唯一字符只调用自己一次。我的答案中的代码应该这样做,因为如果对初始字符串进行了排序,“rest”将始终进行排序(在您的示例中不是这样,您需要在main中调用str上的std::sort,所以它是这样的)非常感谢你们,太棒了,我从来没有想过要再添加一个for循环。。。!