用于排列的 C++ 递归算法 [关闭]

Posted

技术标签:

【中文标题】用于排列的 C++ 递归算法 [关闭]【英文标题】:C++ recursive algorithm for permutation [closed] 【发布时间】:2014-10-27 09:20:35 【问题描述】:

permute() 函数陷入无限循环,我似乎找不到原因? 我尝试通过删除递归调用来检查函数,它似乎工作正常。我也有基本情况,所以不知道问题出在哪里。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

string smallString(string s, int k)    // computes a string removing the character at index k 
    int i,j;
    string res;
    for(i=0,j=0;j<s.length();i++,j++)
        if(i==k)j++;
        res.push_back(s[j]);
    
return res;

void permute(string s1, string s2, size_t len)
    if(len==1)
        cout<<"length is equal to 1"<<(s1+s2)<<'\n'; return; //base case
    else
        for(int i =0;i<len;i++)
            string temp= s2.substr(i,1);
            s1.append(temp);
            string fin = smallString(s2,i);
            //cout<<temp<<'\t'<<s1<<'\t'<<fin<<'\t'<<fin.length()<<'\n';
            permute(s1,fin,fin.length());
            s1.erase((s1.length()-1));
            //cout<<"printing s1 : "<<s1<<'\n';
        
    


int main()
    string s2="abc";
    string s1="";
    permute(s1,s2,s2.length());
    return 0;

【问题讨论】:

这可能会令人震惊,但您正在递归调用permute 这可能会让人感到震惊,但没有一个理智的人会阅读这样的未缩进代码。 IMO,生成排列的逻辑相当复杂。你为什么不开始用调试器调试你自己的代码,在每次递归时显示文本,考虑更小的输入,你最终会发现问题的。 你考虑过std::next_permutation 吗? @nightfold : 用正确的缩进编辑代码 【参考方案1】:

您的问题似乎出在“smallString”函数中。在该函数中,OutOfRange 用于 s[j]。我把打印像

for(i=0,j=0;j<s.length();i++,j++)

    if(i==k)j++;
      cout<<"smallString:: s ::"<<s<<'\t'<<"k::"<<k<<'\n';
    res.push_back(s[j]); //Problem is here...

现在输出打印就像

smallString:: s ::abc k::0

smallString:: s ::abc k::0

smallString:: s ::bc k::0

smallString:: s ::bc k::1

smallString:: s ::bc k::1

smallString:: s ::b k::0

smallString:: s ::b k::1

smallString:: s ::b k::1 . .

因此,在某个时间点,它以“s ::b k::1”的形式出现,因此您正在从字符串“b”中选择位置 1 处的字符。

String 基本上是一个从 0 到 (n-1) 的字符数组。对于字符串“b”,只有第 0 个位置有字符“b”。但我们正在访问一个不存在的位置。

所以它会抛出错误并从这里开始连续循环。

解决您的问题:

for(i=0,j=0;j<s.length();i++,j++)

    if(i==k)
    
        j++;
    
    else
    
        cout<<"smallString:: s ::"<<s<<'\t'<<"k::"<<k<<'\n';
        res.push_back(s[j]);
    

【讨论】:

@Sridhar 感谢您的大力帮助。但只有一次编辑,我应该跳过部分 if(i==k) j++; // 这部分,因为“for循环”为我完成了部分。修改后运行正常,谢谢。

以上是关于用于排列的 C++ 递归算法 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

c++,全排列输出,递归的应用

Heap's Algorithm - Python 中用于生成排列的非递归方法

求全排列

n个整数全排列的递归实现(C++)

c++中扩展欧几里得算法的递归到底发生了啥?

全排列算法(递归)