Kolumna z najmniejszą sumą liczb.

0

Witam. Jestem raczkującym kodziarzem. Mam zadanie tej treści:

Napisz program, który:
a) tworzy tablicę dwuwymiarową liczb całkowitych o rozmiarze N x N i wypełnia tablicę dodatnimi
wartościami pobranymi od użytkownika. W przypadku, gdy użytkownik poda wartość niespełniającą
kryterium, do tablicy wstawiona powinna być wartość 0. N powinno być zdefiniowane jako stała.
b) wypisuje na ekranie numer kolumny o najmniejszej sumie elementów.

W moim kodzie wszystko działa poprawnie do rozpoczęcia ostatniej pętli z zliczaniem sumy w kolumnach, później wszystko się coś psuje. Będę wdzięczny za wskazanie błędu oraz wyjaśnienie przyczyny.

#include <iostream>
#define N 4

using namespace std;

int pozycja(int tab[N][N])
{
    int suma=0, najmniejsza=0, kolumna;
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            cin>>tab[i][j];
            if(isdigit(tab[i][j]) || tab[i][j]<0)
                tab[i][j]=0;
        }
    }
    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)
        {
            suma+=tab[j][i];
        }
        if(suma<najmniejsza);
        {
            najmniejsza=suma;
            kolumna = i+1;
        }
        if(i==0)
            najmniejsza=suma;
        suma=0;
    }
    cout << najmniejsza << endl << suma << endl;
    return kolumna;
}

int main()
{
    int tab[N][N];
    cout<<pozycja(tab);
    return 0;
}
3

Źle sumujesz w danej kolumnie. Zamiast suma += tab[j][i]; powinno być suma += tab[i][j]; to raz.
Dwa, nie masz resetu wartości suma jak przechodzisz do kolejnej kolumny.
Trzy, źle zainicjowana zmienna najmniejsza - zainicjuj ją nie 0, a sumą wartości z kolumny 0 => Etab[<0, N-1>, 0]
EDIT:
A nie, jednak co do uwag 2 i 3 coś tam masz - ale zrobione w sposób podatny na błędy.

0
MasterBLB napisał(a):

Źle sumujesz w danej kolumnie. Zamiast suma += tab[j][i]; powinno być suma += tab[i][j]; to raz.
Dwa, nie masz resetu wartości suma jak przechodzisz do kolejnej kolumny.
Trzy, źle zainicjowana zmienna najmniejsza - zainicjuj ją nie 0, a sumą wartości z kolumny 0 => Etab[<0, N-1>, 0]

  1. O ile się nie mylę, jeżeli dam w tych pętlach suma += tab[i][j];, to otrzymam sumę liczb w każdym wierszu, a mi chodzi o kolumny.
  2. Reset sumy jest umieszczony przed końcem zewnętrznej pętli.
    3.:
        if(i==0)
            najmniejsza=suma;
        suma=0;

Czy źle Cię zrozumiałem?

1
Łukasz Gancarz napisał(a):
  1. O ile się nie mylę, jeżeli dam w tych pętlach suma += tab[j][i];, to otrzymam sumę liczb w każdym wierszu, a mi chodzi o kolumny.
    Czy źle Cię zrozumiałem?

No właśnie źle. W zapisie tablicy 2wymiarowej tab[A][B] najpierw podaje się numer wiersza, a potem kolumny -> czyli w Twoim przypadku wewnętrzna pętla inkrementuje po wierszu a nie kolumnie.

0

No właśnie źle. W zapisie tablicy 2wymiarowej tab[A][B] najpierw podaje się numer wiersza, a potem kolumny -> czyli w Twoim przypadku wewnętrzna pętla inkrementuje po wierszu a nie kolumnie.

Dokładnie, inkrementuje po wierszu, a kolumna zostaje bez zmian. W ten sposób przed przejściem do następnej kolumny zostały zsumowane wszystkie elemeny w kolumnie.

1

Tak to jest, jak się pisze bez 2 kawy...racja, warunek jest OK. Ale mam wątpliwości, czy jeśli najmniejsza suma akurat wypadnie w pierwszej kolumnie to Twój program to wychwyci. Zrób test wprowadzając dane 1, 2, 3, 4 tyle razy, ile będzie trzeba.
Jak nie zadziała to Ci powiem, dlaczego tak się stało.

0
MasterBLB napisał(a):

Tak to jest, jak się pisze bez 2 kawy...racja, warunek jest OK. Ale mam wątpliwości, czy jeśli najmniejsza suma akurat wypadnie w pierwszej kolumnie to Twój program to wychwyci. Zrób test wprowadzając dane 1, 2, 3, 4 tyle razy, ile będzie trzeba.
Jak nie zadziała to Ci powiem, dlaczego tak się stało.

Ogólnie problem jest w jednym miejscu, mianowicie najmniejsza wartość jest prawidłowo przypisywana aż do ostatniego przejścia pętli. Sprawdzałem wyświetlając wartości. Wszystko ładnie śmigało, a w ostatnim przejściu pętli zmienna "najmniejsza" przyjmuje wartość z ostatniej kolumny.

0

Normalnie cuda - dla danych:

    #define ROW_INIT {1, 2, 3, 4}
    int table[N][N] = {ROW_INIT, ROW_INIT, ROW_INIT, ROW_INIT};

jak przychodzi do porównania suma < najmniejsza warunek ten jest zawsze spełniony, nawet jak pod debuggerem jak byk widać, że dajmy na to suma = 8 a najmniejsza = 4 o.O skoro jest spełniony, to zawsze wykonuje nadpisanie najmniejszej aktualną sumą.
Ale czemu tak się dzieje, za Swaroga na razie nie wiem. Pewną wskazówką tutaj jest, że parametr funkcji widzę jako tablicę jednowymiarową.
EDIT:
E, wskazówka niepomocna - po sprawdzeniu pamięci pod adresem tab są wszystkie wiersze i kolumny jak należy.

1

DOBRA, NAMIERZYŁEM DZIADA.
Buga powoduje chędożony średnik ustawiony na końcu linii if(suma<najmniejsza); trzeba go usunąć. Oto nieco dopieszczony kod:

int pozycja(int tab[N][N])
{
    int suma, najmniejsza, kolumna;
//    for(int i=0; i<N; i++)
//    {
//        for(int j=0; j<N; j++)
//        {
//            cin>>tab[i][j];
//            if(isdigit(tab[i][j]) || tab[i][j]<0)
//                tab[i][j]=0;
//        }
//    }

    for (int column = 0; column < N; column++)
    {
        suma = 0;

        for (int row = 0; row < N; row++)
        {
            suma = suma + tab[row][column];
        }

        if (suma < najmniejsza || column == 0)
        {
            najmniejsza = suma;
            kolumna = column + 1;
        }
    }
    cout << najmniejsza << endl << suma << endl;
    return kolumna;
}
0

MasterBLB

Thx! Jestem Twoim fanem

1

Jeszcze jeden błąd się wkradł:

            if(isdigit(tab[i][j]) || tab[i][j]<0)

tab[i][j] jest typu int, natomiast funkcja isdigit służy sprawdzaniu, czy char jest cyfrą, np '0' jest cyfrą, podczas gdy 'a' już nie. Wywołanie funkcji w ten sposób najpierw castuje liczbę na char, a potem sprawdza, czy to co zostało reprezentuje cyfrę w ASCII. Przykładowo, isdigit(4) jest fałszywe, natomiast spróbuj wpisać do komórki 52, i zobacz, że zostanie wpisane 0.

0
enedil napisał(a):

Jeszcze jeden błąd się wkradł:

            if(isdigit(tab[i][j]) || tab[i][j]<0)

tab[i][j] jest typu int, natomiast funkcja isdigit służy sprawdzaniu, czy char jest cyfrą, np '0' jest cyfrą, podczas gdy 'a' już nie. Wywołanie funkcji w ten sposób najpierw castuje liczbę na char, a potem sprawdza, czy to co zostało reprezentuje cyfrę w ASCII. Przykładowo, isdigit(4) jest fałszywe, natomiast spróbuj wpisać do komórki 52, i zobacz, że zostanie wpisane 0.

Jakie rozwiązanie tego problemu mógłbyś zaproponować?

1

To powinno pomóc:

if (cin.fail() || tab[i][j] < 0)
{
   //nie udało się poprawnie wczytać danej do int-a
   tab[i][j] = 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1