jasmin
jasmin

Reputation: 113

How to find which row has the biggest sum in 2D array?

I have 2D array, I need to write a function to find which row has the biggest sum, and if there is more than one row with the same sum, I need to print no particular max. This is what I wrote so far:

int find_max_sum(int b[N][N])
{
    int row_sum = 0;
    int row_max = -1;
    int i,j,k;
    int counter=0;
    for(int i =0;i<N;i++)
    {
        row_sum = 0;
        for (j = 0; j < N; ++j)
        {
            row_sum +=  b[i][j] ;
        }
        if(row_max < row_sum)
        {
            row_max = row_sum;
        }
    }
    for (i = 0; i < N; i++)
    {
       for (j= 0;j< N;j++)
       {
           if(k=row_max);
           counter++;
       }
    }
    if (counter>1)
        return(printf("No unique max.\n"));
    else
        return row_max;
}

Now I need help with the counter thing, and if the function is int how can it return prints? Is it possible?

Upvotes: 0

Views: 4255

Answers (3)

elricfeng
elricfeng

Reputation: 394

Here's an example.

#include <stdio.h>
#include <stdbool.h>

#define N 2
#define NO_UNIQUE -1

int find_max_sum(int b[][N])
{
    int row_sum, i, j;
    int row_max = -1;
    bool unique = false;

    for (i = 0; i < N; ++i) {
        row_sum = 0;
        for (j = 0; j < N; ++j)
            row_sum += b[i][j];

        if (row_max < row_sum) {
            row_max = row_sum;
            unique = true;
        } else if (row_max == row_sum)
            unique = false;
    }

    if (unique)
        return row_max;
    else {
        printf("No unique max.\n");
        return NO_UNIQUE;
    }
}

int main(void)
{
    int b[N][N] = {1, 2, 3, 4};

    printf("Max sum is %d\n", find_max_sum(b));

    return 0;
}

Upvotes: 1

David C. Rankin
David C. Rankin

Reputation: 84561

You may be over-thinking the function, if I understand what you want correctly. If you simply want to return the row index for the row containing a unique max sum, or print no unique max. if the max sum is non-unique, then you only need a single iteration through the array using a single set of nested loops.

You can even pass a pointer as a parameter to the function to make the max sum available back in your calling function (main() here) along with the index of the row in which it occurs. The easiest way to track the uniqueness is to keep a toggle (0, 1) tracking the state of the sum.

An example would be:

int maxrow (int (*a)[NCOL], size_t n, long *msum)
{
    long max = 0;
    size_t i, j, idx = 0, u = 1;

    for (i = 0; i < n; i++) {       /* for each row     */
        long sum = 0;
        for (j = 0; j < NCOL; j++)  /* compute row sum  */
            sum += a[i][j];
        if (sum == max) u = 0;      /* if dup, unique 0 */
        if (sum > max)   /* if new max, save idx, u = 1 */
            max = sum, idx = i, u = 1;
    }
    if (u) {    /* if unique, update msum, return index */
        if (msum) *msum = max;
        return idx;
    }
    fprintf (stderr, "no unique max.\n");
    return -1;  /* return -1 if non-unique */
}

(note: if you don't care about having the max sum available back in the caller, simply pass NULL for the msum parameter)

A short test program could be the following. Simply uncomment the second row to test the behavior of the function for a non-unique max sum:

#include <stdio.h>
#include <stdlib.h>

enum { NCOL = 7 };

int maxrow (int (*a)[NCOL], size_t n, long *msum)
{
    long max = 0;
    size_t i, j, idx = 0, u = 1;

    for (i = 0; i < n; i++) {       /* for each row     */
        long sum = 0;
        for (j = 0; j < NCOL; j++)  /* compute row sum  */
            sum += a[i][j];
        if (sum == max) u = 0;      /* if dup, unique 0 */
        if (sum > max)   /* if new max, save idx, u = 1 */
            max = sum, idx = i, u = 1;
    }
    if (u) {    /* if unique, update msum, return index */
        if (msum) *msum = max;
        return idx;
    }
    fprintf (stderr, "no unique max.\n");
    return -1;  /* return -1 if non-unique */
}

int main (void) {

    int a[][7] = {{ 0, 9, 3, 6, 4, 8, 3 },
            /* { 3, 9, 2, 7, 9, 1, 6 }, uncomment for test */
                { 6, 1, 5, 2, 6, 3, 4 },
                { 4, 3, 3, 8, 1, 2, 5 },
                { 3, 9, 2, 7, 9, 1, 6 }},
        maxidx;
    long sum = 0;
    size_t nrow = sizeof a/sizeof *a;

    if ((maxidx = maxrow (a, nrow, &sum)) != -1)
        printf (" max sum '%ld' occurs at row : %d  (0 - indexed).\n",
                sum, maxidx);

    return 0;
}

Example Use/Output

For the unique sum case:

$ ./array2Drow
 max sum '37' occurs at row : 3  (0 - indexed).

non-unique case:

$ ./array2Drow
no unique max.

Look it over and let me know if you have any questions, or if I misinterpreted your needs.

Upvotes: 0

Jack
Jack

Reputation: 133577

I suggest you to use a third variable (let's call it rowsWithMaxCount) to store the amount of rows with the current max value such that:

  • if you find a row with a new maximum then rowsWithMaxCount = 1
  • if you find a row such that row_max == row_sum then ++rowsWithMaxCount
  • otherwise rowsWithMaxCount is unaffected

This will save you from looping the bidimensional array, which is a waste of code since you can obtain all the information you need with a single traversal of the array.

"returning a printf" doesn't make any sense and it's not possible, if you declare the function to return an int then you must return an int. Consider using a special value to signal the caller that there is no unique maximum value. Eg, assuming values are always positive:

static const int NO_UNIQUE_MAX = -1;

int find_max_sum(int b[N][N]) {
  ...
  if (counter > 1)
    return NO_UNIQUE_MAX;
  ...
}

But this will prevent you from returning the not-unique maximum value. If you need to return both then you could declare a new type, for example

struct MaxRowStatus {
  int value;
  int count;
};

So that you can precisely return both values from the function.

Upvotes: 0

Related Questions