草庐IT

c++ - std::_throw_out_of_range 不知从何而来

coder 2024-02-22 原文

我是 C++ 的绝对初学者。字面上地。才过了一个星期。 今天我在写一个程序来测试需要多少次迭代才能使某个数字回文。 这是代码:

#include <iostream>
#include <string>
#include <algorithm>

/*  This program calculates the steps needed
    to make a certain number palindromic.
    It is designed to output the values for
    numbers 1 to 1000
*/
using namespace std;

class number
{
public:
    string value;
    void reverse();
};

void number::reverse()
{
    std::reverse(value.begin(),value.end());
}

void palindrome(number num)
{
    string n=num.value;
    number reversenum, numsum, numsumreverse;
    reversenum=num;
    reversenum.reverse();
    numsum.value=num.value;
    numsumreverse.value=numsum.value;
    numsumreverse.reverse();
    int i=0;
    while (numsum.value.compare(numsumreverse.value) !=0)
    {
        reversenum=num;
        reversenum.reverse();
        numsum.value=to_string(stoll(num.value,0,10)+stoll(reversenum.value,0,10));
        numsumreverse.value=numsum.value;
        numsumreverse.reverse();
        num.value=numsum.value;
        i++;
    }
    cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}

int main()
{
    number temp;
    int i;
    for (i=1; i<1001; i++)
    {
        temp.value=to_string(i);
        palindrome(temp);
    }
    return 0;
}

对于 195 以下的数字,它会顺利进行。但是,如果是 196,我会收到错误消息。 它说:

terminate called after throwing an instance of 'std::out_of_range' what(): stoll

我不知道该怎么办。我尝试从 196 开始,但错误仍然存​​在。任何帮助将不胜感激。 :)

更新:这次我尝试使用 ttmath 库来完成。但是啊!它再次停在 195,甚至不报告错误!我可能正在做一些愚蠢的事情。如有任何意见,我们将不胜感激。这是更新后的代码:

#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>

/*  This program calculates the steps needed
    to make a certain number palindromic.
    It is designed to output the values for
    numbers 1 to 1000
*/
using namespace std;

class number
{
public:
    string value;
    void reverse();
};

void number::reverse()
{
    std::reverse(value.begin(),value.end());
}

template <typename NumTy>
string String(const NumTy& Num)
{
    stringstream StrStream;
    StrStream << Num;
    return (StrStream.str());
}

void palindrome(number num)
{
    string n=num.value;
    number reversenum, numsum, numsumreverse;
    reversenum=num;
    reversenum.reverse();
    numsum.value=num.value;
    numsumreverse.value=numsum.value;
    numsumreverse.reverse();
    ttmath::UInt<100> tempsum, numint, reversenumint;
    int i=0;
    while (numsum.value.compare(numsumreverse.value) !=0)
    {
        reversenum=num;
        reversenum.reverse();
        numint=num.value;
        reversenumint=reversenum.value;
        tempsum=numint+reversenumint;
        numsum.value=String<ttmath::UInt<100> >(tempsum);
        numsumreverse.value=numsum.value;
        numsumreverse.reverse();
        num.value=numsum.value;
        i++;
    }
    cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
}

int main()
{
    number temp;
    int i;
    for (i=196; i<1001; i++)
    {
        temp.value=to_string(i);
        palindrome(temp);
    }
    return 0;
}

更新:已解决。一些研究表明 196 可能是 Lychrel Number .在暗示 ttmath 库后我得到的结果只是让我确信我的算法有效。我已经尝试了所有高达 10000 的数字,它给出了完美的结果。这是最终代码:

#include <iostream>
#include <string>
#include <algorithm>
#include <ttmath/ttmath.h>
#include <limits>

/*  This program calculates the steps needed
    to make a certain number palindromic.
    It is designed to output the values for
    numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;

class number
{
public:
    string value;
    void reverse();
};

void number::reverse()
{
    std::reverse(value.begin(),value.end());
}

template <typename NumTy>
string String(const NumTy& Num)
{
    stringstream StrStream;
    StrStream << Num;
    return (StrStream.str());
}

void palindrome(number num)
{
    string n=num.value;
    number reversenum, numsum, numsumreverse;
    reversenum=num;
    reversenum.reverse();
    numsum.value=num.value;
    numsumreverse.value=numsum.value;
    numsumreverse.reverse();
    ttmath::UInt<100> tempsum, numint, reversenumint;
    int i=0;
    while ((numsum.value.compare(numsumreverse.value) !=0) && i<200)
    {
        reversenum=num;
        reversenum.reverse();
        numint=num.value;
        reversenumint=reversenum.value;
        tempsum=numint+reversenumint;
        numsum.value=String<ttmath::UInt<100> >(tempsum);
        numsumreverse.value=numsum.value;
        numsumreverse.reverse();
        num.value=numsum.value;
        i++;
    }
    if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num.value << endl;
    else
    {
        cout << "A solution for " << n << " could not be found!!!" << endl;
        LychrelList=LychrelList+n+" ";
        LychrelCount++;
    }
}

int main()
{
    cout << "From where to start?" << endl << ">";
    int lbd,ubd;
    cin >> lbd;
    cout << endl << "And where to stop?" << endl <<">";
    cin >> ubd;
    cout << endl;
    number temp;
    int i;
    for (i=lbd; i<=ubd; i++)
    {
        temp.value=to_string(i);
        palindrome(temp);
    }
    if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
    cout << endl << endl << "Press ENTER to end the program...";
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    string s;
    getline(cin,s);
    cout << "Thanks for using!";
    return 0;
}

这是一个非常棒的社区。特别鸣谢Marco A . :)

再次更新:我设计了自己的 add() 函数来减少程序对外部库的依赖。它导致更小的可执行文件和更快的性能。这是代码:

#include <iostream>
#include <string>
#include <algorithm>
#include <limits>

/*  This program calculates the steps needed
    to make a certain number palindromic.
    It is designed to output the values for
    numbers inside a desired range
*/
using namespace std;
string LychrelList;
int LychrelCount=0;

string add(string sA, string sB)
{
    int iTemp=0;
    string sAns;
    int k=sA.length()-sB.length();
    int i;
    if (k>0){for (i=0;i<k;i++) {sB="0"+sB;}}
    if (k<0) {for (i=0;i<-k;i++) {sA="0"+sA;}}
    for (i=sA.length()-1;i>=0;i--)
    {
        iTemp+=sA[i]+sB[i]-96;
        if (iTemp>9)
        {
            sAns=to_string(iTemp%10)+sAns;
            iTemp/=10;
        }
        else
        {
            sAns=to_string(iTemp)+sAns;
            iTemp=0;
        }
    }
    if (iTemp>0) {sAns=to_string(iTemp)+sAns;}
    return sAns;
}

void palindrome(string num)
{
    string n=num;
    string reversenum, numsum, numsumreverse;
    numsum=num;
    numsumreverse=numsum;
    reverse(numsumreverse.begin(),numsumreverse.end());
    int i=0;
    while ((numsum.compare(numsumreverse) !=0) && i<200)
    {
        reversenum=num;
        reverse(reversenum.begin(),reversenum.end());
        numsum=add(num,reversenum);
        numsumreverse=numsum;
        reverse(numsumreverse.begin(),numsumreverse.end());
        num=numsum;
        i++;
    }
    if (i<200) cout << "The number " << n << " becomes palindromic after " << i << " steps : " << num << endl;
    else
    {
        cout << "A solution for " << n << " could not be found!!!" << endl;
        LychrelList=LychrelList+n+" ";
        LychrelCount++;
    }
}

int main()
{
    cout << "From where to start?" << endl << ">";
    int lbd,ubd;
    cin >> lbd;
    cout << endl << "And where to stop?" << endl <<">";
    cin >> ubd;
    cout << endl;
    string temp;
    int i;
    for (i=lbd; i<=ubd; i++)
    {
        temp=to_string(i);
        palindrome(temp);
    }
    if (LychrelList.compare("") !=0) cout << "The possible Lychrel numbers found in the range are:" << endl << LychrelList << endl << "Total - " << LychrelCount;
    cout << endl << endl << "Press ENTER to end the program...";
    cin.ignore(numeric_limits<streamsize>::max(), '\n');
    string s;
    getline(cin,s);
    cout <<endl << "Thanks for using!";
    return 0;
}

你们帮了我很多,让我找到了自己的路。感谢大家。 :)

最佳答案

num.valuereversenum.value 的最后两个有效值以来,您正在溢出 long long > 是 7197630720180367016 和 6107630810270367917,它们加在一起远远超过 long long 的最大大小(在我的机器上是 9223372036854775807)。这将产生负值并破坏您对 stoll

的下一次调用

std::out_of_range is thrown if the converted value would fall out of the range of the result type or if the underlying function (std::strtol or std::strtoll) sets errno to ERANGE.

( reference )

  • 如果你想得到下一个最小的回文,你应该使用另一种方法,比如I explained here。 .

你可以找到一个 Live Example 这里

  • 如果您喜欢/必须继续您的方法,您应该在字符串上手动添加或使用 bigint 库(再次查看 here 并修改 plusOne() 功能根据你的喜好)

关于c++ - std::_throw_out_of_range 不知从何而来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32807269/

有关c++ - std::_throw_out_of_range 不知从何而来的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  5. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  6. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  7. ruby 代码 : why put colon in front of variable name (inside initialize method) - 2

    我遇到了一些Ruby代码,我试图理解为什么变量在initialize方法声明中的名称末尾有冒号。冒号有什么原因吗?attr_reader:var1,:var2definitialize(var1:,var2:)@var1=var1@var2=var2end 最佳答案 那些是关键字参数。您可以按名称而非位置使用它们。例如ThatClass.new(var1:42,var2:"foo")或ThatClass.new(var2:"foo",var1:42)Anarticleaboutkeywordargumentsbythoughtbot

  8. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  9. ruby - 让 bundler 使用 http : instead of git:? - 2

    我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://

  10. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

随机推荐