Piksele, praca z plikiem.txt

1

W pliku tekstowym mam 200 wierszy, w kazdym wierszu 320 liczb naturalnych od 0 do 255, oddzielone pojedynczymi znakami spacji. Zadanko mam takie:
Podaj długość najdłuższej linii pionowej (czyli ciągu kolejnych pikseli w tej samej kolumnie obrazka), złożonej z pikseli tej samej jasności.
Moge dostac jakas wskazowke?

for(int i=0; i<200; i++)
for(int j=0; j<320; j++)

Co zrobic, zeby ta petla zagniezdzona(wewnetrzna) najpierw sprawdzala wszystkie liczby w kolumnach?

1

Co zrobic, zeby ta petla zagniezdzona(wewnetrzna) najpierw sprawdzala wszystkie liczby w kolumnach?

Mam nadzieję, że dobrze rozumiem Twoje zadanie, jeśli tak to zacząłbym od warunku pikseli z tej samej jasności.
Kod poniżej jest przykładowy, pisałem go na szybko jako zarys całego rozwiązania:

for(int i=0; i<200; i++)
{
    int lastPixelBrightness = MeasureBrightness( pixelMatrix[i][0] );
    for(int j=0; j<320; j++)
    {
        if( lastPixelBrightness == MeasureBrightness( pixelMatrix[i][j] ) )
            samePixelLineLength++;
        else
            samePixelLineLength = 0;

        lastPixelBrightness = MeasureBrightness( pixelMatrix[i][j] );
    }
}

Krótko mówiąc: Zaczynasz od pierwszego elementu w danej kolumnie i pobierasz jasność pierwszego piksela metodą MeasureBrightness dalej lecisz w dół macierzy porównując i inkrementując długość linii jednakowych pikseli, czyli zmiennej samePixelLineLength.


Podaj długość najdłuższej linii pionowej (czyli ciągu kolejnych pikseli w tej samej kolumnie obrazka), złożonej z pikseli tej samej jasności.
Moge dostac jakas wskazowke?

Na koniec pomiaru linii jednakowych pikseli dla każdej kolumny zachowujesz tą długość (na przykład w tablicy wszystkich długości, może być vector).
Gdy zmierzysz najdłuższe takie linie w całej macierzy sprawdzasz, która długość jest maksymalna spośród zapamiętanych i jej indeks w tablicy, lub w vectorze jest jednocześnie numerem kolumny Twojej macierzy z pliku.

To tyle. Spróbuj zaimplementować co trzeba i wróć gdy będziesz miał jeszcze jakieś problemy/pytania.

edit: Poprawiłem przykładowy kawałek kodu - zapamiętywanie ostatniej jasności.

1

Co zrobic, zeby ta petla zagniezdzona(wewnetrzna) najpierw sprawdzala wszystkie liczby w kolumnach?

Tworzysz sobie vector< vector<int>> gdzie pierwszy vector to cala kolumna a int to wartosc tego. Teraz wystarczy ze wczytasz caly plik do vectora i mozesz robic sprawdzanie po kolei (jako, ze vector zawiera kolumne)
Drugim sposobem bedzie uzycie std::map<int, vector<int> gdzie pierwsza wartosc kolumny a drugi to zbior liczb w tej kolumnie

0

@Bartosz36:
Trochę nie rozumiem podstaw. Dla mnie zewnętrzna pętla (i) jest odpowiedzialna za wiersze, a wewnętrzna (j) za kolumny.
Czyli np dla i=0 sa sprawdzane wszystkie liczby (j) dla zerowego wiersza. Czy poprawnie rozumuję?

0

Dla mnie zewnętrzna pętla (i) jest odpowiedzialna za wiersze

To zależy jak rozumiesz "odpowiedzialna za wiersze". Ogólnie chodzi o to, że:
W pętli for(int i=0; i<200; i++) przesuwasz się po kolejnych kolumnach, powiedzmy: po osi OX.
Natomiast w pętli: for(int j=0; j<200; j++) przesuwasz się po kolejnych pikselach wybranej kolumny. Czyli po osi OY.
Obrazując:

  A B C D
0
1
2
3

W pierwszej pętli pobierasz kolumnę A, natomiast inkrementując j przesuwasz się po wierszach 0, 1, ... wybranej kolumny A.

0

To skoro jest 320 kolumn i 200 wierszy, dlaczego pierwszą pętlą jest i-200?
Ta pierwsza ma przeciez odpowiadać za kolumny (oś OX) a ich jest 320
Mam straszne braki w podstawach podstaw i wciaz nie moge tego zrozumiec :(

1

dlaczego pierwszą pętlą jest i-200?

Za bardzo skupiasz się na samym kodzie, który Ci napisałem. Ten kawałek kodu miał Ci jedynie dać zarys rozwiązania, nie samo rozwiązanie gotowe do przekopiowania. ;)
Jeśli kolumn jest 320, to w pierwszej pętli podstaw liczbę 320. Analogicznie w drugiej pętli - jeśli wierszy jest 200 podstaw tam 200.
Tak naprawdę łatwiej byłoby Ci się w tym połapać, gdybyś nie stosował tzw magic numbers a zamiast tego zastosował coś w stylu:

constexpr int columns = 320;
constexpr int rows    = 200;

Wtedy i ja mógłbym Ci w tym kodzie napisać for(int i=0; i<columns; i++) nie myląc 320 z 200.

0

Proponuję podzielić problem na 320 mniejszych problemów i szukać maksymalnego rozwiązania.

0

Z gory przepraszam za czytelnosc kodu, na razie zalezy mi na logicznym ogarnieciu podstaw.
Kompiluje sie, daje zle wyniki. Wiem gdzie lezy blad - w deklarowaniu tablicy, a potem operacjach na petlach - czyli to o co pytalem o gory.
Wklejam poprawny kod, a w nawiasach dam co ja pisze w programie i nie wiem czemu jest zle.

wczytanie do tablicy:

int tablica[200][320]; // tablica[320][200] - zakladam najpierw kolumny (OY), potem wiersze (OX)
  int variable;

for (int i=0; i<200; i++){ // i<320 (kolumny)
        for (int j=0; j<320; j++) // j<200 (wiersze)
        {
            file>>variable;
            tablica[i][j] = variable;
        }
}

program:

int longest_tmp; int longest_tmp_count = 1;
int longest_count = 0;

        for (int j=0; j<320; j++){ // i=0; i<320; i++ (bo najpierw kolumny)
        for (int i=0; i<200; i++){ // j=0; j<200; j++ (do każdej kolumny sprawdzam wszystkie wiersze)

                if(j==0){
                longest_tmp = tablica[i][j];
                longest_tmp_count = 1;
                }

                else
                {
                    if (tablica[i][j]==longest_tmp)
                    {
                        longest_tmp_count++;
                    }

                    else
                    {
                        if(longest_count < longest_tmp_count) longest_count = longest_tmp_count;
                        longest_tmp = tablica[i][j];
                        longest_tmp_count = 1;
                    }

                }
        }
        }
        cout<<longest_count;

Dlaczego tak mieszają się działania na pętlach? We wczytaniu do tablicy wewnątrz jest i-ta pętla, ale już w programie wewnątrz jest j-ta pętla? Nie ma większego znaczenia w jakiej kolejności wczytamy pętle?

0

Nie rozumiem tego fragmentu:

for (int i=0; i<200; i++){ // i<320 (kolumny)
for (int j=0; j<320; j++) // j<200 (wiersze)

Dlaczego komentarze przeczą temu co jest rzeczywiście w kodzie?
Po drugie jak powyższy kod wczytywania do tablicy ma się do:

for (int j=0; j<320; j++){ // i=0; i<320; i++ (bo najpierw kolumny)
for (int i=0; i<200; i++){ // j=0; j<200; j++ (do każdej kolumny sprawdzam wszystkie wiersze)

Moim zdaniem jeśli gubisz się w tym co jest w końcu kolumnami a co wierszami (czyli co jest osią X a co osią Y) to zrób to na vectorach. Tak jak radził @fasadin, będziesz miał wtedy wyraźnie zdefiniowane wiersze i kolumny. Wektor wektorów, czyli wektor kolumn, z których każda jest wektorem jasności pikseli.
To proste:

std::vector< std::vector< pixelBrightness_t > > pixelColumns;

// Wiec teraz moge odwolywac sie do kolumn, nie myslac czy to 320, 200 czy co innego:
pixelColumns[ 0 ];    // Pierwsza kolumna jasnosci pikseli
pixelColumns[ i ];     // i-ta kolumna jasnosci pixeli, nie wazne ile tych kolumn jest.

A ile tych kolumn jest? Tyle ile wykryjesz podczas wczytywania tablicy. Napotykasz nową kolumnę (czyli nowy znak po spacji w wierszu o numerze 0) i robisz:

std::vector< pixelBrightness_t > nextColumn;
// Tutaj wypełniasz nextColumn wszystkimi pikselami z danej kolumny
pixelColumns.push_back( nextColumn );

Spróbuj, warto korzystać z STL.

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