【问题标题】:Generating lexicographic permutations: Segmentation fault生成字典排列:分段错误
【发布时间】:2013-08-10 08:50:24
【问题描述】:

我有这个代码来生成字典排列。使用如下逻辑:

  1. 从给定测试字符串中字符的升序排列开始。
  2. 要生成下一个字典排列:

a) 找到比下一个字符小的最右边的字符。说一个。

b) 在 A 的右边,找到下一个更大的字符。说 B。然后交换 A 和 B。

c) 在A的原位置右侧,按升序排列字符。

当我们得到最后一个排列时,算法结束。即给定测试字符串的反转。 我的测试字符串s = "0123456789"

编辑: 在程序的每次运行中,我都会得到一个单独的分段错误位置。

得到A:

int firstchar(string s){
int pos = s.length()-2;
for(int i=pos;i>=0;i--){
    if(s[i]<s[i+1]){
        pos = i;
        break;
    }
}
return pos;}

得到B然后递归的方法(qsort是来自&lt;cstdlib&gt;的函数):

int ceilchar(string s, int fc){
int ceil = fc+1;
int diff=27;
for(int i=ceil;i<s.length();i++){
    if(s[i]>s[fc] && s[i]-s[fc]<diff){
        ceil = i;
        diff  = s[i]-s[fc];
    }
}
return ceil;}

开始功能:

void nextpermute(string& s){
int fc = firstchar(s);
int cc = ceilchar(s,fc);
swap(s,fc,cc);
sort(&s[fc]+1,&s[fc]+s.length()-fc);
if(s!="9876543210"){
    cout<<s<<"\n";
    nextpermute(s);
}
else
    cout<<s<<"\n";}

主呼叫:nextpermute(test);

如果测试字符串是"01234567" 或任何比这更小的字符串,它运行良好。但如果它是一个类似的字符串 "012345678""0123456789" ,然后我得到分段错误。 请帮忙!!

【问题讨论】:

  • std::next_permutation 有什么问题?
  • @chris 我正在尝试自己解决这个问题。一旦通过,我肯定会使用它
  • 为什么你使用strcmps.c_str() 而不是operator==s?您已设法获取安全代码并使其不安全。
  • 哦,是的!刚刚从我的脑海中滑落,我可以直接比较字符串对象。无论如何,这仍然不能解决我的问题。
  • 如果你遇到了段错误,你应该在调试器中运行你的代码来确定是哪一行导致了问题。然后从那里向后工作。

标签: c++ c segmentation-fault permutation lexicographic


【解决方案1】:

我怀疑您的堆栈大小超出了限制。如果您在 Linux 上运行它,请执行“限制”并查看您的堆栈大小。有两种方法可以避免这种情况

1) (不推荐)做“限制堆栈大小无限制”(仅当您使用基于 unix 的系统时)。然后再次运行程序。

2)(推荐)。

改变

void nextpermute(string& s){
    int fc = firstchar(s);
    int cc = ceilchar(s,fc);
    swap(s,fc,cc);
    sort(&s[fc]+1,&s[fc]+s.length()-fc);
    if(s!="9876543210"){
        cout<<s<<"\n";
        nextpermute(s);
    }
    else
        cout<<s<<"\n";
}

void nextpermute(string& s){
    int fc = firstchar(s);
    int cc = ceilchar(s,fc);
    swap(s,fc,cc);
    sort(&s[fc]+1,&s[fc]+s.length()-fc);
    cout <<s<<"\n";
}

并将您的主要功能修改为

int main()
{
    string s = "0123456789";
    while (s != "9876543210")
    {
        nextpermute(s);
    }
}

以上更改将取消“nextpermute”的递归,因此您的堆栈大小限制将永远不会被超过

【讨论】:

  • 是的,我将代码更改为迭代过程!它起作用了,顺便说一句,我如何/在哪里写“限制堆栈大小无限制”?
  • 在启动二进制文件之前,您必须在 shell 中给出命令。顺便说一句,限制是 csh/tcsh 命令。如果您使用 bash,请执行“ulimit -s unlimited”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-22
相关资源
最近更新 更多