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

时间:2018-11-09 07:23:46

标签: c++ arrays average temperature

我需要在平均温度最高的数组中查找行。有两个主要变量,一个指示有多少天进行温度测量,另一个指示每天有多少次测量。幸运的是,在我尝试过的大多数情况下,该程序的确显示了平均温度最高的正确日期。但是,在某些情况下,例如以下情况,它不起作用,我无法弄清原因。

如果我插入以下值:

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

2 个答案:

答案 0 :(得分:1)

John,很明显,您在理解需要将哪些值作为参数传递给函数以及如何处理循环以根据数据获取最大的每日平均值方面有些挣扎。

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

关键是为您的功能选择有意义的返回 type,以便您可以return所需的信息。由于您正在验证在array中读入main()的数据(不是吗?),因此几乎不需要选择返回类型来表示计算成功/失败,而是选择{{ 1}}根本没有提供任何好处,您只能通过参考。

虽然这行得通,但还有一种更基本的方法来处理返回值-仅将void的值设为return所需类型的值。这样就完全不需要传递main()。函数始终可以返回自己的类型。但是,什么类型? largest是一个不错的选择,因为将double除以sum的数目将得到浮点数的值-除非您打算整数除法发生。

更改measurements的返回类型,并重新排列循环,以便每天计算largestaveragesum并在第二天正确重新初始化,并包含avg,以便您可以使用标准方法将<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/measurements\n";
        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/measurements\n";
        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

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

让C ++完成大部分工作

尽管在C ++中使用基本数组类型和手动$ ./bin/dailyavg < file largest daily avg: 12.3333 循环绝对没有问题,但出于所有实际目的,您的代码以及上面的代码除了使用for之外都是标准C代替cin/cout并使用scanf/printf代替numeric_limits<double>::min()

我们拥有C ++的原因是使事情变得更容易。代替DBL_MIN声明一个具有自动存储持续时间的整数数组和每个int array[100][100]的{​​{1}}数组的固定范围,您可以使用100并让C ++处理范围和内存管理为您服务。您无需使用固定范围的循环,而只需使用自动范围 100 int循环(C ++ 11)即可对填充的内容进行循环。 (这也消除了将边界传递给函数的需要,而只需传递对vector<vector<int>> array;的引用即可。)

您可以简单地使用for循环每日数据以求和每一天的值,然后简单地除以每日向量的array,而不是内部循环和外部循环求和每天的平均值。

让C ++为您完成大部分工作会减少手动循环,求和和求平均值的次数,例如

accumulate

(您甚至可以不需要读取数据文件的第一行,而只需使用.size()将日期读为#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/measurements\n"; 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; } 并创建string并使用{ {1}}到getlinestringstream

两种方法都很好,第一种基本上是C语言,没有任何问题,第二种方法利用了C ++的一些优点。仔细研究一下,如果您还有其他问题,请告诉我。

答案 1 :(得分:0)

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

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

另外,就像提到的“ @Someprogramme dude”一样,最好是在循环外计算平均值。

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

largest=-1000;