【问题标题】:C++ Find the sum of elements between minimum and maximum element of matrixC ++查找矩阵的最小和最大元素之间的元素之和
【发布时间】:2020-11-09 21:37:25
【问题描述】:

所以,我的程序可以正常工作,但前提是最小和最大元素在对角。 所以我的问题是如何将二维数组从一个特定元素迭代到另一个元素(也许摆脱一些嵌套循环)。我要把这个数组转换成一维吗?

这是代码的正确工作:

这是出现问题的时候。元素 {0}{1} 和 {1}{1} 丢失了。

这是代码的缩短变体:

#include <iostream>

using namespace std;

void matrix_count(int a[5][5],int min, int max, int min_i, int min_j, int max_i, int max_j) {
    int suma = 0;
    int counter = 0;
    if (min_i <= max_i && min_j <= max_j) { 
        for (int i = 0; i < 5; i++) {       //iterating all matrix
            for (int j = 0; j < 5; j++) {
                if (a[i][j] == min) {       //start a new cycle when find min
                    for (int i = min_i; i < 5; i++) {
                        for (int j = min_j; j < 5; j++) {
                            if (a[i][j] == max) { i = 5; break; }
                            else if (a[i][j] != min) {
                                counter++;
                                suma += a[i][j];
                                cout << a[i][j] << " ";
                            }
                        }
                    }
                }
            }
        }
    }
    else if (min_i >= max_i && min_j <= max_j) {} // min[i]<max[i] min[j]<max[j]
    else if (min_i <= max_i && min_j >= max_j) {} // min[i]<max[i] min[j]>max[j]
    else if (min_i >= max_i && min_j >= max_j) {} // min[i]>max[i] min[j]>max[j]
    cout << endl;
    cout << suma << endl;
    cout << counter << endl;
}

int main()
{
    int a[5][5] = { 
        {0,4,6,3,5},
        {7,1,5,6,2},
        {6,8,8,5,2},
        {4,1,5,2,2},
        {4,3,6,5,9} };
    int min = a[0][0];
    int max = a[0][0];
    int max_i = 0;
    int min_i = 0;
    int max_j = 0;
    int min_j = 0;

// finding the max
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (a[i][j] > max) {
                max = a[i][j];
                max_i = i;
                max_j = j;
            }
        }
    }

// finding the min
    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 5; j++) {
            if (a[i][j] < min) {
                min = a[i][j];
                min_i = i;
                min_j = j;
            }
        }
    }

    matrix_count(a, min, max, min_i, min_j, max_i, max_j);

    return 0;
}

【问题讨论】:

  • "我的问题是如何将二维数组从一个特定元素迭代到另一个元素(也许还可以摆脱一些嵌套循环)。" - 请把它分解为少量。 - 另外:把你的代码变成minimal reproducible example
  • 所以我的问题是如何将二维数组从一个特定元素迭代到另一个元素 -- 鉴于你拥有的数组类型,它与你拥有一个一维数组,因为二维数组在连续内存中具有数据布局。这只是弄清楚起始索引和结束索引的问题。例如,该数组实际上是7 6 0 3 5 7 1 5 9 2 6 8 8 5 2 4 1 5 2 2 4 3 6 5 9。另外,请将数据作为文本发布,而不是作为图像发布。
  • elements {0}{1} and {1}{1} got lost 尚不清楚如何将{0}{1} 视为“介于最小和最大元素之间”。这里的“介于”到底是什么意思?
  • 仅供参考:我看不到您显示的任何图片。介意以纯文本形式分享?
  • 整个程序只需要一个循环就可以实现,忘记它是二维的,使用指针遍历矩阵。在评估每个元素时存储 min,max,sum。应该有一堆 if in-place 来实现逻辑。既然在我看来这是一个家庭作业,我想我不应该写它,对吧?祝你好运。

标签: c++ matrix


【解决方案1】:

正如我的评论所述,一种解决方案是意识到二维数组在连续内存中具有其数据布局。这样得到最小值、最大值和总和就变得简单了,因为您可以像遍历一维数组一样遍历二维数组。

这是一个使用 C++ 算法函数的解决方案。

#include <algorithm>
#include <iostream>
#include <numeric>

int main()
{
    int a[5][5] = {
        {0,4,6,3,5},
        {7,1,5,6,2},
        {6,8,8,5,2},
        {4,1,5,2,2},
        {4,3,6,5,9} };

    // Get both the position of the minimum and maximum element in the array  
    auto pr = std::minmax_element(&a[0][0], &a[4][5]);

    // add up all elements between the min and max elements 
    int answer = std::accumulate(std::next(pr.first), pr.second, 0);

    // output results
    std::cout << answer;
}

输出:

100

是的,这就是整个代码。

那么做了什么?

首先,我们使用std::minmax_element 遍历数组,从指向第一个元素的指针(&amp;a[0][0]) 到传递最后一个元素的指针(&amp;a[4][5])。请注意该函数的参数——之所以有效,是因为二维数组具有我前面提到的连续布局。所以这只是一个弄清楚开始和结束位置的问题。

std::minmax_element 的返回值是一个std::pair&lt;int*, int*&gt;,它指向最小元素(first)和最大元素(second)。这就是pr 的含义。

完成后,我们可以使用std::accumulate 和来自pr 的指针快速将最小元素和最大元素之间的项目相加。

请注意,std::accumulate 的第一个参数是找到的最小值之后的下一个值。这就是第一个参数中std::next 的原因——它将我们带到下一个值。

【讨论】:

    【解决方案2】:

    问题是您只是从 min_i 迭代到 5。在这个 for 语句中:
    for (int i = min_i; i &lt; 5; i++)
    这意味着每一行都将从min_i开始。

    解决此问题的一种简单方法是首先迭代该行的其余部分,如下所示:

    for(int i = min_i+1; i < 5; i++) {
        if (a[i][j] == max) { i = 5; break; }
        counter++;
        suma += a[i][min_j];
    }
    

    然后通过以下循环遍历剩余的内容:

    for (int i = 0; i < 5; i++) {
        for (int j = min_j+1; j <= max_j; j++) {
            if (a[i][j] == max) { i = 5; break; }
            counter++;
            suma += a[i][j];
            cout << a[i][j] << " ";
        }
    }
    

    但总的来说,我真的建议您多考虑一下您的代码,因为您所做的所有事情都可以通过对整个矩阵进行一次迭代来完成。此外,直到达到最小值的前两个循环不仅令人困惑(您正在重用 j 和 i),而且也是不必要的。您可以直接从min_i+1 开始,就像我上面显示的代码一样。

    【讨论】:

      【解决方案3】:

      虽然已经给出了答案,但我还是分享一下我个人的解决方案,我正在使用转换数组到一维。

      #include <iostream>
      
      using namespace std;
      
      const int N = 5;
      const int M = 5;
      
      void matrix_count(int a[N * M], int min , int max, int min_i, int max_i) {
          int counter = 0;
          int sum = 0;
          printf("\n\n");
          if (min_i <= max_i) {
              for (int i = min_i + 1; i < N * M; i++) {
                  if (a[i] == max) { break; }
                  counter++;
                  sum += a[i];
                  cout << a[i] << " ";
              }
          }
          else if (min_i >= max_i) {
              for (int i = max_i + 1; i < N * M; i++) {
                  if (a[i] == min) { break; }
                  counter++;
                  sum += a[i];
                  cout << a[i] << " ";
              }
          }
          printf("\n\n");
          cout <<"sum = "<< sum << endl;
          cout << "number of elements = " <<counter << endl;
          printf("\n");
          for (int i = 0; i < N*M ; i++) a[i] = 0;
      }
      
      void find_min(int a_one[N * M], int &min, int &min_i) {
          for (int i = 0; i < N * M; i++) {
              if (a_one[i] < min) {
                  min = a_one[i];
                  min_i = i;
              }
          }
          printf("\nMin_i = %d", min_i);
          printf("\nMin = %d", min);
      }
      
      void find_max(int a_one[N * M], int& max, int& max_i) {
          for (int i = 0; i < N * M; i++) {
              if (a_one[i] > max) {
                  max = a_one[i];
                  max_i = i;
              }
          }
          printf("\nMax_i = %d", max_i);
          printf("\nMax = %d", max);
      }
      void convert_arr(int a1[N][M],int a_one[N*M], int &i_one) {
          for (int i = 0; i < 5; i++) {
              for (int j = 0; j < 5; j++)
              {
                  a_one[i_one] = a1[i][j];
                  i_one++;
                  cout << a1[i][j] << " ";
              }
              printf("\n");
          }
      }
      
      int main()
      {
          setlocale(0, "");
          int max_i = 0;
          int min_i = 0;
          int a1[N][M] = {
              {6,4,6,3,9},
              {7,1,5,6,2},
              {0,8,8,5,2},
              {4,1,5,2,2},
              {4,3,6,5,7} };
          int a_one[N * M] = {};
          int i_one = 0;
      
          convert_arr(a1, a_one, i_one);
      
          int min_1 = a_one[0];
          find_min(a_one, min_1, min_i);
      
          int max_1 = a_one[0];
          find_max(a_one, max_1, max_i);
      
          matrix_count(a_one, min_1, max_1, min_i, max_i);
      
          return 0;
      }
      
      

      【讨论】:

        猜你喜欢
        • 2014-04-08
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 2017-01-03
        • 2021-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多