Piksele, praca z plikiem.txt

Odpowiedz Nowy wątek
2018-03-12 08:51
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?

edytowany 2x, ostatnio: Joff3R, 2018-03-12 09:13
O bożu, toż to zadanie z mojej maturki, już współczuję, przejechałem się nań - enedil 2018-03-12 11:26
@enedil: da się te wszystkie zadania w ogóle rozwiązać pisząc kod(cpp)? chyba czasu nie starczy - WeiXiao 2018-03-12 12:33
@WeiXiao: ja miałem 90%, napisałem wszystko, tylko wkradły się literówki, generalnie miałbym 100%. Pisałem w cpp. Znam ludzi, co mieli 96%, 98%, 100%. - enedil 2018-03-12 12:51
Jeśli kogoś ciekawi, to jest kod, który naskrobałem w trakcie matury (spot the typo): https://gist.github.com/enedil/8a6bcf0fe49a67132d3b493e5300c1bc - enedil 2018-03-12 12:56
@enedil: I feel ya bro, ale te wyniki o których piszesz nieosiągalne w moim technikum xd - Burdzi0 2018-03-12 17:34

Pozostało 580 znaków

2018-03-12 09:56
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.

edytowany 1x, ostatnio: Bartosz36, 2018-03-12 10:06

Pozostało 580 znaków

2018-03-12 10:01
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

Pozostało 580 znaków

2018-03-12 11:24
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ę?

Pozostało 580 znaków

2018-03-12 11:31
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.

Pozostało 580 znaków

2018-03-12 15:22
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 :(

Pozostało 580 znaków

2018-03-12 15:47
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.

edytowany 1x, ostatnio: Bartosz36, 2018-03-12 15:47
Oki, masz rację, nie doczytałem, że to tylko szkic :) - Joff3R 2018-03-12 15:52

Pozostało 580 znaków

2018-03-12 17:18
0

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

edytowany 1x, ostatnio: Azarien, 2018-03-12 17:18

Pozostało 580 znaków

2018-03-12 17:48
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?

edytowany 3x, ostatnio: Joff3R, 2018-03-12 17:51

Pozostało 580 znaków

2018-03-13 10:10
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.

Pokaż pozostałe 3 komentarze
Sorry, ale mapa jest nie tylko wolniejsza tutaj, jest też mniej użyteczna. Napisz kod, który udowodni, że nie mam racji. - enedil 2018-03-13 11:48
Nie mówiąc już o tym, że jest brzydsza. - enedil 2018-03-13 11:49
Równie dobrze możesz iterować po vectorze: for (auto& wiersz: vec) - enedil 2018-03-13 11:51
@enedil: Istnieje możliwość edytowania swoich komentarzy - nie trzeba spamować pojedynczymi zdaniami. Po drugie: Tu nie chodzi o wywoływanie gównoburzy pomiędzy std::vector a std::map, wystarczy porównać ich Big-O ;) Po trzecie: Nie ma czegoś takiego jak brzydszy/ładniejszy kontener - jeśli potrafisz pisać czysty kod, to będziesz pisał czysty kod wykorzystując oba te kontenery. Proponuję tutaj zakończyć tą dyskusję w komentarzach i nie zaśmiecać ani wątku, ani pojedynczego posta. - Bartosz36 2018-03-13 12:20
Skupiając się na konkretach: Tak, Big-O vectora, dostęp do elementu o danym indeksie jest O(1), czyli lepiej niż w map, w której jest O(log |mapy|) (gwarantowane). Przecież i tak proponowana była map<int, vector<int>>. Naprawdę nie rozumiem, dlaczego w tym miejscu użycie mapy miałoby byś wydajniejsze (jeśli nie rozumiem usecase, to wytłumacz proszę - i tak potrzeba gęsto upakowanych indeksów). - enedil 2018-03-13 18:56

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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