1

我必须从 5 个数组中找到 4 个数字的最大和,并以相同的方式找到最小和。我的代码在一些较大的测试用例中失败,因为由于某种原因最大值变为负数

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int minimini(int list[]){
    int minisum=0;
    int taker;
    int a=max({list[0],list[1],list[2],list[3],list[4]});
    for (int i=0; i<5; i++){
        taker=list[i];
        if(taker!=a){
            minisum=minisum+taker;
        }
    }
return minisum;
}
int maxa(int list[]){
    int maxsum=0;
    int taker;
    int a=min({list[0],list[1],list[2],list[3],list[4]});
    for (int i=0; i<5; i++){
        taker=list[i];
        if(taker!=a){
            maxsum=maxsum+taker;
            cout<<"maxsum >>"<<maxsum;
            cout<<"a="<<a;
        }
    }
return maxsum;
}
int main(){
    int list[5];
    int minisum, maxsum;
    for (int i=0; i<5; i++){
        cin>>list[i];
    }

    minisum=minimini(list);
    maxsum=maxa(list);

    cout<<minisum<<" "<<maxsum;


    return 0;
}
4

4 回答 4

4

您的代码遭受Integer Overflow的影响。大多数现代计算机中的整数范围从 -2,147,483,6482,147,483,647. 由于您在评论中提到您的输入可以从 1 到 10^9 并且数组的大小是5,因此最大总和可以是5 * 10^9,这确实大于2,147,483,647。您只需要一个可以容纳更大值的数据类型,使用:

  1. long long
  2. std::int64_t

请注意,甚至unsigned int不会完成这项工作,因为它是4,294,967,295< 5 * 10^9。另一件事是之间的区别

A. int a = 2,147,483,647 ; int b = 2,147,483,647 ; long long k = a + b.现在,由于ab是整数,因此在将其分配回之前会发生溢出,long long因为整数加法也就是32 bit加法会发生。

long long a = 2,147,483,647; long long b = 2,147,483,647; long long k = a + b。。现在,溢出不会发生,因为加法将被执行,long long因为 a 和 b 是long long并且64 bit加法会发生

代码如下所示:

long long list[5]; //See int is now long long
long long minisum, maxsum;

for (int i=0; i<5; i++) //i can be int because it's size of list i.e 5
{
    cin>>list[i];
}

minisum=minimini(list);
maxsum=maxa(list);

cout<<minisum<<" "<<maxsum;
于 2020-01-08T07:07:48.510 回答
3

int 类型有它的范围:

int: -2,147,483,648 to 2,147,483,647

如果使用 long long int 类型会更好。

long long int: -(2^63) to (2^63)-1

以下是我的测试代码,请参考 LernerCpp 的注释以附加 typedef 语句:

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;

typedef long long int INT64;

INT64 minimini(INT64 list[]){
    INT64 minisum=0;
    INT64 taker;
    INT64 a=max({list[0],list[1],list[2],list[3],list[4]});
    for (int i=0; i<5; i++){
        taker=list[i];
        if(taker!=a){
            minisum=minisum+taker;
        }
    }
return minisum;
}
INT64 maxa(INT64 list[]){
    INT64 maxsum=0;
    INT64 taker;
    INT64 a=min({list[0],list[1],list[2],list[3],list[4]});
    for (int i=0; i<5; i++){
        taker=list[i];
        if(taker!=a){
            maxsum=maxsum+taker;
            cout<<"maxsum >>"<<maxsum<<endl;
            cout<<"a="<<a<<endl;
        }
    }
return maxsum;
}
int main(){
    INT64 list[5];
    INT64 minisum, maxsum;
    // int: -2,147,483,648 to 2,147,483,647
    // long long int:   -(2^63) to (2^63)-1
    for (int i=0; i<5; i++){
        std::string tmp;
        char* pEnd=0;
        printf("enter number %d:\n",i);
        cin>>tmp;
        list[i]=strtoll(tmp.c_str(),&pEnd,10);
        printf("number %d: %lld\n",i,list[i]);
    }

    printf("the list array are: [%lld,%lld,%lld,%lld,%lld,]\n",list[0],list[1],list[2],list[3],list[4]);

    minisum=minimini(list);
    maxsum=maxa(list);

    cout<<minisum<<" "<<maxsum;


    return 0;
}

coliru 现场演示

结果:

C:\Users\s41167\Documents\mingw-w64>test_maximum.exe
enter number 0:
10000000000
number 0: 10000000000
enter number 1:
-10000000000
number 1: -10000000000
enter number 2:
20000000000
number 2: 20000000000
enter number 3:
-20000000000
number 3: -20000000000
enter number 4:
30000000000
number 4: 30000000000
the list array are: [10000000000,-10000000000,20000000000,-20000000000,300000000
00,]
maxsum >>10000000000
a=-20000000000
maxsum >>0
a=-20000000000
maxsum >>20000000000
a=-20000000000
maxsum >>50000000000
a=-20000000000
0 50000000000
C:\Users\s41167\Documents\mingw-w64>

和 ANIKET LAVKUSH VISHWAKARMA 19B 的输入:

C:\Users\s41167\Documents\mingw-w64>test_maximum.exe
enter number 0:
256741038
number 0: 256741038
enter number 1:
623958417
number 1: 623958417
enter number 2:
467905213
number 2: 467905213
enter number 3:
714532089
number 3: 714532089
enter number 4:
938071625
number 4: 938071625
the list array are: [256741038,623958417,467905213,714532089,938071625,]
maxsum >>623958417
a=256741038
maxsum >>1091863630
a=256741038
maxsum >>1806395719
a=256741038
maxsum >>2744467344
a=256741038
2063136757 2744467344
C:\Users\s41167\Documents\mingw-w64>
于 2020-01-08T07:10:08.497 回答
1

虽然int范围确实是一个问题,但我很难理解的是为什么您不会使用任何新的 C++ 功能,例如:

#include <iostream>
#include <array>
#include <algorithm>
#include <numeric>

using lli_t = long long int;

int main(){
    std::array<int,5> list;

    for (int i=0; i<list.size(); i++){
        std::cin>>list[i];
    }

    std::sort(std::begin(list), std::end(list));

    auto minsum = std::accumulate(std::begin(list), std::begin(list)+4, static_cast<lli_t>(0));
    auto maxsum = std::accumulate(std::begin(list)+1, std::end(list), static_cast<lli_t>(0));

    std::cout << minsum << " " << maxsum;

    return 0;
}
于 2020-01-08T09:56:00.510 回答
0

整数数据类型只能保存从 -2,147,483,647 到 2,147,483,647 [1] 的值。解决此问题的一种简单方法是将所有int声明更改为floator doubleorlong数据类型。

[1] https://www.ibm.com/support/knowledgecenter/en/SSGU8G_12.1.0/com.ibm.sqlr.doc/ids_sqr_122.htm

于 2020-01-08T06:50:04.847 回答