找出阵列中哪一行的平均温度最高



我需要在数组中找到平均温度最大的行。有两个主要变量,一个表示有多少天进行了温度测量,另一个表示每天进行了多少次测量。幸运的是,在我尝试过的大多数情况下,该程序确实显示了平均温度最高的正确日期。然而,在某些情况下,例如以下情况,它不起作用,我不知道为什么。

如果我插入以下值:

4 3

8 8 10

12 10 7

14 12 11

11 10 12

它应该显示2,因为这是平均温度最高的一天。但是,由于某些原因,它反而显示一个0。

这是我正在使用的代码:

include <iostream>
using namespace std;
void largestaverage (int array[100][100], int amountDays, int amountMeasurements, int &largest, int &largestDay, int dailyAverage)
{
largest=array[0][0];
largestDay=0;
for(int i=0; i<amountDays; i++)
{
dailyAverage=0;
for(int k=0; k<amountMeasurements; k++)
{
dailyAverage+=array[i][k];
dailyAverage=dailyAverage/amountMeasurements;
if(dailyAverage>largest)
{
largest=array[i][k];
largestDay=i;
}
}
}
}
int main ()
{
int array[100][100], amountDays, amountMeasurements, largest, largestDay, dailyAverage=0;
cin>>amountDays;
cin>>amountMeasurements;
for (int i=0; i<amountDays; i++)
{
for (int k=0; k<amountMeasurements; k++)
{
cin>>array[i][k];
}
} 
largestaverage (array, amountDays, amountMeasurements, largest, largestDay, dailyAverage);
cout<<largestDay<<endl;
return 0;
}

John,很明显,您在理解需要将哪些值作为参数传递给函数以及如何处理循环以获得基于数据的最大日平均值方面有点困难。

首先,唯一需要传递给largestaverage()的参数是数组本身,以及指示每天使用的daysmeasurements数量的边界。仅凭这些信息,你就可以计算出最大的日均值——但如何将最大的日均数返回到main(),以便使用呢?

关键是为您的函数选择一个有意义的返回type,这样您就可以return所需的信息。由于您正在验证main()中读取到array的数据(不是吗?),因此几乎不需要选择返回类型来指示计算的成功/失败,但选择void根本没有任何好处,您只能通过引用。

虽然这会起作用,但还有一种更基本的方法来处理返回——只需return,即所需类型的main()的值。这就完全不需要通过largest。函数总是可以返回自己的类型。但是,什么类型?double是一个不错的选择,因为sum除以measurements的结果将产生浮点值——除非您打算进行整数除法

更改largestaverage的返回类型,重新排列循环,以便每天计算sumavg,并在第二天正确地重新初始化,包括<limits>,以便使用标准方法将largest初始化为type可用的最小值,您可以执行类似的操作:

...
#include <limits>   /* for numeric_limits */
...
#define MAXDM 100   /* if you need a constant, #define one (or more) */
/* choose a meaningful return type, and return a value */
double largestaverage (int array[][MAXDM], int days, int msrmts)
{
/* initialize largest sufficiently small (all vals could be negative) */
double largest = std::numeric_limits<double>::min();
for (int i = 0; i < days; i++) {        /* loop over each day */
int sum = 0;                        /* initialize sum/avg */
double avg = 0;
for (int k = 0; k < msrmts; k++)    /* loop over measurements */
sum += array[i][k];             /* compute sum */
avg = sum / (double)msrmts;         /* compute avg */
if (avg > largest)                  /* check against largest */
largest = avg;
}
return largest;                         /* return largest */
}

重新排列main()并为每个输入添加所需的验证,您可以执行类似于以下操作:

int main (void) {
int array[MAXDM][MAXDM] = {{0}},    /* declare/initialize variables */
days, measurements;
if (!(cin >> days >> measurements)) {   /* VALIDATE read of input */
cerr << "error: invalid format for days/measurementsn";
return 1;
}
for (int i = 0; i < days; i++)          /* loop over days */
for (int k = 0; k < measurements; k++)  /* loop over measurements */
if (!(cin>>array[i][k])) {      /* VALIDATE read of input */
cerr << "error: invalid format row '" << k + 1 << "'n";
return 1;
}
/* output results */
cout << "largest daily avg: " 
<< largestaverage (array, days, measurements) << endl;
}

把它放在一个简短的例子中,会得到:

#include <iostream>
#include <limits>   /* for numeric_limits */
using namespace std;
#define MAXDM 100   /* if you need a constant, #define one (or more) */
/* choose a meaningful return type, and return a value */
double largestaverage (int array[][MAXDM], int days, int msrmts)
{
/* initialize largest sufficiently small (all vals could be negative) */
double largest = std::numeric_limits<double>::min();
for (int i = 0; i < days; i++) {        /* loop over each day */
int sum = 0;                        /* initialize sum/avg */
double avg = 0;
for (int k = 0; k < msrmts; k++)    /* loop over measurements */
sum += array[i][k];             /* compute sum */
avg = sum / (double)msrmts;         /* compute avg */
if (avg > largest)                  /* check against largest */
largest = avg;
}
return largest;                         /* return largest */
}
int main (void) {
int array[MAXDM][MAXDM] = {{0}},    /* declare/initialize variables */
days, measurements;
if (!(cin >> days >> measurements)) {   /* VALIDATE read of input */
cerr << "error: invalid format for days/measurementsn";
return 1;
}
for (int i = 0; i < days; i++)          /* loop over days */
for (int k = 0; k < measurements; k++)  /* loop over measurements */
if (!(cin>>array[i][k])) {      /* VALIDATE read of input */
cerr << "error: invalid format row '" << k + 1 << "'n";
return 1;
}
/* output results */
cout << "largest daily avg: " 
<< largestaverage (array, days, measurements) << endl;
}

示例输入

$ cat file
4 3
8 8 10
12 10 7
14 12 11
11 10 12

示例使用/输出

$ ./bin/dailyavg < file
largest daily avg: 12.3333

第三天输入对应的最大平均值。

让C++完成大部分工作

虽然在C++中使用基本数组类型和手动for循环绝对没有错,但出于所有实际目的,除了使用cin/cout代替scanf/printf和使用numeric_limits<double>::min()代替DBL_MIN之外,您的代码和上面的代码都只是标准C。

我们使用C++的原因是为了让事情变得更容易。与int array[100][100]声明一个具有自动存储持续时间的整数数组以及每个100 int100数组的固定边界不同,您可以使用vector<vector<int>> array;并让C++为您处理边界和内存管理。您只需使用自动范围for循环(C++11)来循环填充的内容,而不是在某些固定边界上循环。(这也消除了将边界传递给函数的需要,而只需传递对array的引用)。

您可以简单地循环使用accumulate对每日数据求和,然后简单地除以每日向量的.size(),而不是内部和外部循环对每个每日平均值进行求和和和计算。

让C++为您完成大部分工作可以减少手动循环、求和和和求平均所需的数量,例如

#include <iostream>
#include <vector>   /* for vector */
#include <numeric>  /* for accumulate */
#include <limits>   /* for numeric_limits */
using namespace std;
/* choose a meaningful return type, and return a value */
double largestaverage (vector<vector<int>>& array)
{
/* initialize largest sufficiently small (all vals could be negative) */
double largest = std::numeric_limits<double>::min();
for (auto day : array) {            /* loop over each day vector */
double avg = accumulate (day.begin(), day.end(), 0) / 
static_cast <double>(day.size()); /* compute avg */
if (avg > largest)              /* check against largest */
largest = avg;
}
return largest;                     /* return largest */
}
int main (void) {
vector<vector<int>> array;          /* declare vector of vectors */
int days, measurements;
if (!(cin >> days >> measurements)) {   /* VALIDATE read of input */
cerr << "error: invalid format for days/measurementsn";
return 1;
}
for (int i = 0; i < days; i++) {        /* loop over days */
vector<int> tmp;
for (int k = 0; k < measurements; k++) { /* loop over measurements */
int msrmt;
if (!(cin >> msrmt)) {      /* VALIDATE read of input */
cerr << "error: invalid format row '" << k + 1 << "'n";
return 1;
}
tmp.push_back(msrmt);       /* add msrmt to tmp vector */
}
array.push_back(tmp);           /* add tmp vector to array */
}
/* output results */
cout << "largest daily avg: " << largestaverage(array) << endl;
}

(您甚至可以消除读取数据文件第一行的需要,只需使用getline将日期读取为string,然后创建stringstream并使用>>循环到int.push_back())

这两种方法都很好,第一种基本上是C,没有任何问题,第二种利用了C++的一些细节。仔细看看,如果你还有问题,请告诉我。

将最大值设置为您看到的最大平均值,而不是largest=array[i][k]

if(dailyAverage>largest)
{
largest=dailyAverage;
largestDay=i;
}

此外,就像"@Some programmer dude"提到的那样,最好是在循环之外计算平均值。

编辑:将最大值初始化为一个小得不可思议的数字,因为这很可能会导致逻辑错误。

largest=-1000;

最新更新