在使用向量时抛出“std::out_of_range”错误实例后调用终止

问题描述

#include<iostream>
#include<vector>
using namespace std;
int count=0;
int checkDivisor(int d,int*ptr){
    vector<int> v;
    int temp=0;
for (int i = *ptr; ; i++)
{
   for (int j = 1; j<=i; j++)
   {
       if(i%j==0){
           v.push_back(j);
           count++;
       }
   }
   if (count>=4)
   {
       temp=i;
      break;
   }
   else
   {
       v.clear();
   }
}
for(int k=0;k<v.size();k++){
    if ((v.at(k+1)-v.at(k))<=d)
    {
       return 0;
    }
}
return temp;
}

int main(){
int t;
cin>>t;
while (t>0)
{   
    int d;
    cin>>d;
    int value=0;
    int*point=&value;
    int result=checkDivisor(d,point);
    if(result==0){
        *point++;
        checkDivisor(d,point);
    }
    else{
    cout<<checkDivisor(d,point)<<endl;
    }
    t--;
}
return 0;
}

在抛出'std::out_of_range'的实例后,这将返回一个错误终止调用 what(): vector::_M_range_check: __n (1) >= this->size() (1)。 我想要做的是返回一个数字,如果它有 3 个以上的除数并且任何两个除数之间的差大于 d 请帮忙。

解决方法

std::vector::at 进行范围检查。错误发生在您尝试访问 for (k=0; k < v.size(); ++k)v.at(k+1) 循环中。这在 k=v.size()-1 时越界。另外,您有什么理由将 ptr 作为指针传递吗?我建议按值传递。你的逻辑也有几个问题。这是一个有效的示例(适用于正数):

#include<iostream>
#include<vector>
#include<limits>
std::vector<int> try_get_first_n_divisors(const int number,const int n)
{
    std::vector<int> v;
    for (int divisor = 1; divisor <= number; divisor++)
    {
        // check if it is a divisor of number
        if(number%divisor==0)
        {
            // is so,add it to the vector
            v.push_back(divisor);

            // When we found more than four divisors,leave the loop
            if(v.size() == 4)
                break;
        }  
    }
    return v;
}

bool check_divisor_dist_cirterion(int d,int number){

    std::vector<int> v = try_get_first_n_divisors(number,4);
    
    if (v.size() < 4)
        return false;
    else
    {
        // check the distance between divisors
        for(int k=1; k<v.size(); ++k){
            if ((v.at(k)-v.at(k-1)) <= d)
            {
                return false;
            }
        }
    }
    return true;
}

int main(){ 

    int d;
    std::cin>>d;
    int number = 4;
    while(!check_divisor_dist_cirterion(d,number) 
        && (number < std::numeric_limits<int>::max()))
    {
        ++number;
    }
    
    std::cout << "found " << number << " with divisors ";
    for (auto divisor : try_get_first_n_divisors(number,4))
        std::cout << "  " << divisor;
    std::cout << std::endl;

    return 0;
}

live demo

请注意,您通过检查标准的数字也是一个除数。如果要更改此设置,则必须在 < 中使用 try_get_first_n_divisors 比较:for (int divisor = 1; divisor < number; divisor++)

此外,此示例未优化。例如,如果距离 > 1,那么您可以跳过偶数,因为 1,2 将始终是除数,从而违反您的标准。

注意我没有检查负数的逻辑。

,

此代码 if ((v.at(k+1)-v.at(k))<=d) 获取索引 k+1 处的数字。但是当 k 等于 v.size()-1 k+1 等于 v.size() 时,这是一个超出范围的错误。

现在已经指出了这一点,我相信这对您来说是显而易见的。您应该培养查看自己的代码并了解其功能的能力,尤其是当错误消息准确地告诉您您做错了什么时。

大概是这段代码

for(int k=0;k<v.size();k++){

应该是这个

for(int k=0;k<v.size()-1;k++){

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...