C ++查找矩阵的最小和最大元素之间的元素总和

时间:2020-11-06 23:57:48

标签: c++ matrix

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

这是代码的正确工作:

Here's correct work of the code

这是什么地方出了问题。元素{0} {1}和{1} {1}丢失了。

enter image description here

这是代码的缩写形式:

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

3 个答案:

答案 0 :(得分:3)

正如我的评论所述,一种解决方案是认识到二维数组的数据在连续内存中具有布局。这样,获得最小值,最大值和和就变得很简单,因为您将以与一维数组相同的方式遍历二维数组。

这是使用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遍历数组,从指针指向第一个元素(&a[0][0])到最后一个元素(&a[4][5])传递的数组。注意函数的参数-之所以起作用,是因为二维数组具有我前面提到的连续布局。因此,只需要弄清楚开始位置和结束位置即可。

std::minmax_element的返回值是一个std::pair<int*, int*>,它指向最小元素(first)和最大元素(second)。 pr就是这个意思。

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

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

答案 1 :(得分:1)

问题在于您只从min_i迭代到5。在此for语句中:
for (int i = min_i; i < 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开始。

答案 2 :(得分:0)

即使已经给出了答案,我也会分享我的个人解决方案,其中我将转换数组用于一维。

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