【问题标题】:Sorting biggest and smallest value in array C++对数组C ++中的最大值和最小值进行排序
【发布时间】:2017-08-01 04:49:13
【问题描述】:

这是一个非常简单且常见的练习,尽管我遇到了一个我似乎无法理解的错误,并且我无法在任何地方找到解释,因为它可能太具体了。

程序只是提示用户输入第 1 到第 10 个人吃了多少煎饼,然后打印出某人吃的最多煎饼数量。我的问题是排序最大和最小值的“手工循环”有效,但是算法(在这个论坛上强烈推荐使用而不是手工循环)没有打印出正确的 最大值,但适用于最小

这是我的代码:

void pancakes() {
    int pan[11];
    int small, big;
    for (int i = 1; i < 11; i++)  // counts to 11-1 and prompts user for pancakes
                                  // eaten by person 1==>10
    {
        cout << "How many pancakes did person " << i << " eat?\n";
        cin >> pan[i];
    }

    big = small = pan[1];  // assigns element to be highest or lowest value

    for (int i = 1; i < 11; i++) {
        if (pan[i] > big)  // compare biggest value with current "big" element
        {
            big = pan[i];
        }
        if (pan[i] < small)  // compares smallest value with current "small" element
        {
            small = pan[i];
        }
    }
    cout << "The person who ate the most pancakes ate " << big << " of them."
             << endl;  // prints biggest value
    cout << "The person who ate the least pancakes ate " << small << " of them."
             << endl;  // prints smallest value

    auto minmax = minmax_element(begin(pan), end(pan));

    cout << "min element " << *(minmax.first) << "\n";
    cout << "max element " << *(minmax.second) << "\n";
}   

这是控制台返回的内容:

How many pancakes did person 1 eat?
45
How many pancakes did person 2 eat?
64
How many pancakes did person 3 eat?
7
How many pancakes did person 4 eat?
34
How many pancakes did person 5 eat?
87
How many pancakes did person 6 eat?
45
How many pancakes did person 7 eat?
89
How many pancakes did person 8 eat?
32
How many pancakes did person 9 eat?
55
How many pancakes did person 10 eat?
66
The person who ate the most pancakes ate 89 of them.
The person who ate the least pancakes ate 7 of them.
min element 7
max element 1606416304

【问题讨论】:

    标签: c++ arrays algorithm loops sorting


    【解决方案1】:
    auto minmax = minmax_element(begin(pan), end(pan));
    

    确实找到了最小值/最大值,但 C++ 中的数组索引从 0 开始。您从 1 索引开始填充 int pan[11];

    big=small=pan[1]; //assigns element to be highest or lowest value; change to pan[0]
    for (int i = 1; i < 11; i++){...} // change to i=0
    

    所以pan[0] 将包含垃圾,minmax_element 将考虑这些垃圾(在您的情况下为值1606416304)。

    事实上,在 C 和 C++ 中,从未初始化的变量中读取是未定义的行为,任何事情都可能发生,尽管大多数时候您只是读取了存储在该内存地址的内容。

    如果您使用 C++11(您现在应该使用),那么您也可以使用 range-based for loop 来处理煎饼 :)

    for(auto& pancake: pan) // note the reference, we are reading
    {
        cin >> pancake; // to read
    }
    

    for(auto pancake: pan)
    {
        // further processing here, like
        if(pancake < small) { small = pancake;} // etc
    }
    

    【讨论】:

      【解决方案2】:

      您有一个大小为 11 的数组,但您确实只循环了 10 个元素,而第一个元素未初始化。这意味着它包含垃圾(未定义的行为),在这种情况下为 1606416304,这是最大值,不是吗? =)

      从以下位置更改循环:

      for (int i = 1; i < 11; i++)
      

      到:

      for (int i = 0; i < 11; i++)
      

      std::minmaxelement() 然后按照您的意愿工作。


      后果:

      一般来说,在使用提供与预期结果不同的功能时,一个常见的错误是检查您的数据,您提供了该功能。这样你就知道数据是否有问题或/和功能。在您的情况下,打印数组会让您明白您的数据不正确!

      【讨论】:

      • 啊,我明白了!但实际上我不初始化 pan[0] 的原因是因为我不想提示第 0 个人吃了多少煎饼。由于实际原因,我根本不允许对数组做这些事情吗?
      • 您不必提示输入 Person 0,在您的打印语句中您可以将 &lt;&lt; i &lt;&lt; 更改为 &lt;&lt; i + 1 &lt;&lt;
      • 是的,我现在明白了,我将从pan[0] 开始并添加i+1 非常感谢大家!
      • 或者,可以使用begin(pan)+1 调用minmax_element
      • @gsamaras 是的,同意:)
      【解决方案3】:

      您的 pan 数组被定义为具有 11 元素,但您只初始化了其中的 10 个。值得注意的是,pan[0] 永远不会被初始化,并且会有一些随机值。我猜你的随机值恰好是 1606416304。

      【讨论】:

        猜你喜欢
        • 2016-07-13
        • 2016-07-13
        • 2021-11-30
        • 1970-01-01
        • 2017-02-13
        • 1970-01-01
        • 1970-01-01
        • 2021-12-01
        • 2017-06-13
        相关资源
        最近更新 更多