需要帮助获取阵列上最小的三个数字

时间:2016-11-09 12:38:28

标签: c++

对于此计划,用户必须输入10名参赛者以及他们完成游泳比赛所需的秒数。我的问题是我必须输出第一,第二和第三个位置,所以我需要得到三个最小的阵列(因为它们是最快的时间),但我不确定如何做到这一点。到目前为止,这是我的代码。

string names[10] = {};
int times[10] = { 0 };
int num[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int min1 = 0, min2 = 0, min3 = 0;

cout << "\n\n\tCrawl";

for (int i = 0; i < 10; i++)
    {
        cout << "\n\n\tPlease enter the name of contestant number " <<   num[i] << ": ";
        cin >> names[i];

        cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
        cin >> times[i];
        while (!cin)
        {
            cout << "\n\tError! Please enter a valid time: ";
            cin.clear();
            cin.ignore();
            cin >> times[i];
        }

        if (times[i] < times[min1])
            min1 = i;


        cout << "\n\n\t----------------------------------------------------------------------";
    }
    system("cls");

    cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
    cout << "\n\n\t1st Place - " << names[min1];
    cout << "\n\n\t2nd Place - " << names[min2];
    cout << "\n\n\t3rd Place - " << names[min3];
}
_getch();
return 0;
}

如您所见,它不完整。我知道如何获得最小的数字,但它是给我带来麻烦的第二和第三小数字。

4 个答案:

答案 0 :(得分:0)

您的代码充满了错误:

你对min2和min3做什么,只要你不指定它们?他们总是0

尝试检查:cout << min2 << " " << min3;

你也没有像这样初始化一串字符串。

为什么使用整数数组来打印输入数量: NUM?相反,你可以使用i inside循环每次添加1

  • 解决您的问题使用一种好方法,所以考虑使用结构/群集:

    struct Athlete
    {
        std::string name;
        int time;
    };
    
    int main()
    {   
        Athlete theAthletes[10];
    
        for(int i(0); i < 10; i++)
        {
            std::cout << "name: ";
            std::getline(std::cin, theAthletes[i].name);
            std::cin.sync(); // flushing the input buffer
    
            std::cout << "time: ";
            std::cin >> theAthletes[i].time;
            std::cin.sync(); // flushing the input buffer
        }
    
        // sorting athletes by smaller time
        for(i = 0; i < 10; i++)
            for(int j(i + 1); j < 10; j++)
                if(theAthletes[i].time > theAthletes[j].time)
                {
                    Athlete tmp    = theAthletes[i];
                    theAthletes[i] = theAthletes[j];
                    theAthletes[j] = tmp;
                }
        // printing the first three athletes
        std::cout << "the first three athelets:\n\n";
        std::cout << theAthletes[0].name << " : " << theAthletes[0].time << std::endl;
        std::cout << theAthletes[1].name << " : " << theAthletes[1].time << std::endl;
        std::cout << theAthletes[2].name << " : " << theAthletes[2].time << std::endl;
        return 0;
    }
    

答案 1 :(得分:0)

我希望这会给你预期的输出。但我建议你使用一些排序alogirthms,如冒泡排序,快速排序等。

#include <iostream>
#include<string>

using namespace std;

int main() {

int times[10] = { 0 };
int num[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int min1 = 0, min2 = 0, min3 = 0,m;
string  names[10] ;

cout << "\n\n\tCrawl";

for (int i = 0; i < 10; i++)
    {
        cout << "\n\n\tPlease enter the name of contestant number " <<   num[i] << ": ";
        cin >> names[i];
        cout << names[i];
        cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
        cin >> times[i];
        cout<<times[i];
        while (!cin)
        {
            cout << "\n\tError! Please enter a valid time: ";
            cin.clear();
            cin.ignore();
            cin >> times[i];
        }

if(times[i]==times[min1]){
   if(times[min1]==times[min2]){
                min3=i;


   }else{min2 =i;}

            }else if(times[i]==times[min2]){
                min3=i;
            }
        if (times[i] < times[min1]){

            min1 = i;
            cout <<i;

        }

            int j=0;
            while(j<i){
                if((times[j]>times[min1])&&(times[j]<times[min2])){

                    min2 =j;
                    j++;
                }

                j++;
            }
      m=0;
            while(m<i){
                if((times[m]>times[min2])&&(times[m]<times[min3])){

                    min3 =m;
                    m++;
                }

                m++;
            }
        cout << "\n\n\t----------------------------------------------------------------------";
    }


    cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
    cout << "\n\n\t1st Place - " << names[min1];
    cout << "\n\n\t2nd Place - " << names[min2];
    cout << "\n\n\t3rd Place - " << names[min3];

return 0;

}

答案 2 :(得分:0)

标准库中实际上有一个算法可以完全满足您的需求:std::partial_sort。像其他人之前指出的那样,要使用它,您需要将所有参与者数据放入单个结构中。

首先定义一个包含所有相关数据的结构。因为在我看来,你只使用参赛者的数量,以便能够以最快的时间找到游泳者的名字,我就摆脱它。当然,如果你愿意的话,你也可以把它重新加入。

struct Swimmer {
    int time;
    std::string name;
};

由于您知道在比赛中总会有10名参与者,您也可以继续使用std::array替换C风格的数组。

然后,用户阅读的代码可能如下所示:

std::array<Swimmer, 10> participants;

for (auto& participant : participants) {
    std::cout << "\n\n\tPlease enter the name of the next contestant: ";
    std::cin >> participant.name;

    std::cout << "\n\tPlease enter the time it took for them to complete the Crawl style: ";
    while(true) {
        if (std::cin >> participant.time) {
            break;
        }
        std::cout << "\n\tError! Please enter a valid time: ";
        std::cin.clear();
        std::cin.ignore();       
    }
    std::cout << "\n\n\t----------------------------------------------------------------------";
}

部分排序现在基本上是单行的:

std::partial_sort(std::begin(participants),
                  std::begin(participants) + 3,
                  std::end(participants),
                  [] (auto const& p1, auto const& p2) { return p1.time < p2.time; });

最后,您只需输出数组中前三个参与者的名称:

std::cout << "\n\n\tThe top three winners of the Crawl style race are as follows";
std::cout << "\n\n\t1st Place - " << participants[0].name;
std::cout << "\n\n\t2nd Place - " << participants[1].name;
std::cout << "\n\n\t3rd Place - " << participants[2].name << std::endl;

可以在coliru上找到完整的工作代码。

答案 3 :(得分:-1)

这不是您问题的完整解决方案,但只是为了指出正确的方向......

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

template <int N>
struct RememberNsmallest {
    int a[N];
    RememberNsmallest() { std::fill_n(a,N,std::numeric_limits<int>::max()); }
    void operator()(int x){
        int smallerThan = -1;
        for (int i=0;i<N;i++){
            if (x < a[i]) { smallerThan = i; break;}
        }
        if (smallerThan == -1) return;
        for (int i=N-1;i>smallerThan;i--){ a[i] = a[i-1]; }
        a[smallerThan] = x;
    }
};


int main() {
    int a[] = { 3, 5, 123, 0 ,-123, 1000};
    RememberNsmallest<3> rns;
    rns = std::for_each(a,a+6,rns);
    std::cout << rns.a[0] << " " << rns.a[1] << " " << rns.a[2] << std::endl;
    // your code goes here
    return 0;
}

这将打印

-123 0 3

您还需要知道最佳时间的名称,您应该使用

struct TimeAndName {
    int time;
    std::string name;
}

更改上面的仿函数以取TimeAndName而不是int并使其记住名称......或者提出不同的解决方案;),但无论如何你应该使用类似于TimeAndName的结构。

由于您的数组相当小,您甚至可以考虑使用std::vector<TimeAndName>并使用自定义std::sort通过TimeAndName::operator<对其进行排序。