簡體   English   中英

我必須從 5 個數組中找到 4 個數字的最大和。我的代碼對於更大的數字失敗

[英]I have to find the maximum sum of 4 numbers from an array of 5. My code fails for bigger numbers

我必須以相同的方式從 5 個數組中找到 4 個數字的最大和,以及一個最小和。 我的代碼在一些較大的測試用例中失敗了,因為由於某種原因,maxsum 變為負數

#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;
}

您的代碼受到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 int a = 2,147,483,647 ; int b = 2,147,483,647 ; long long k = a + b int a = 2,147,483,647 ; int b = 2,147,483,647 ; long long k = a + b 。現在,由於ab是整數,因此在將其分配回long long之前會發生溢出,因為會發生整數加法又名32 bit加法。

B. long long a = 2,147,483,647; long long b = 2,147,483,647; long long k = a + b long long a = 2,147,483,647; long long b = 2,147,483,647; long long k = a + b 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;

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>

雖然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;
}

整數數據類型只能保存從 -2,147,483,647 到 2,147,483,647 [1] 的值。 解決此問題的一種簡單方法是將所有int聲明更改為floatdoublelong數據類型。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM