Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Jak napisać poprawne sortowanie alfabetyczne ?

jolkajolka 27 Cze 2012 19:39 2548 21
  • #1 27 Cze 2012 19:39
    jolkajolka
    Poziom 12  

    Piszę program i mam problem z posortowaniem alfabetycznym linijek. Mam segmentation fault i nie wiem dlaczego. Funkcja wholetext, pobiera cały tekst, rozdzielając go na linijki w których literki pobierane są funkcją fgetc. (Funkcja wholetext działa poprawnie i wyświetla mi to co chcę) Jak napisać poprawne sortowanie? Wklejam fragmenty kodu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 21
  • #3 27 Cze 2012 20:10
    jolkajolka
    Poziom 12  

    W funkcji wholetext();, używam malloca a później gdy elementów jest więcej używam realloca i zwiększam wielkość dwa razy.

    0
  • #5 27 Cze 2012 23:59
    jolkajolka
    Poziom 12  

    "Próbowałaś"...:)
    Nie przekraczam, zresztą wszystko się poprawnie wyświetla. Co do debuggera, używałam go, ale to mi nie pomogło, może nie umiem jeszcze go sprawnie obsługiwać. Ale... usuwałam części kodu, żeby sprawdzić kiedy jest segmentation fault i okazało się, że to się pojawia przy warunku ifa (usuwam wnętrze ifa i mam segmentation fault, for działa poprawnie). Pomyślałam, że może coś źle wpisuję do strcmp, ale gdy zrobiłam

    Kod: c
    Zaloguj się, aby zobaczyć kod
    to poprawnie wyświetliło 1, bez żadnego segmentation fault. Więc nie wiem....

    0
  • Pomocny post
    #6 28 Cze 2012 01:02
    sedr
    Poziom 17  

    Zamień proszę to:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    na to:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    W C tablica o n elementach jest indeksowana od 0 do n-1.

    Również tutaj będzie problem:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    ponieważ znowu przekroczysz zakres. Musisz zmiejszyć ilość przebiegów pętli for.

    Mam nadzieję, że jest to jakaś baaaardzo prosta wersja algorytmu sortowania. Ten niestety nie zadziała, ponieważ porównuje jedynie po dwie kolejne linijki, więc musisz to dopracować.

    0
  • #7 28 Cze 2012 06:18
    Dżyszla
    Poziom 42  

    jolkajolka napisał:
    "Próbowałaś"...:)
    Sorry, to z rozpędu ;)

    Jak rozumiem, to bąbelki miały być? Ale poprzednim dobrze mówi z indeksami ;)

    Co do debuggera - po prostu uruchamia się najczęściej F8 (lub ustawia brakpointa na pierwszej linii) i tym klawiszem linia po linii wykonuje. Aczkolwiek może się zdarzyć tak, że tego typu błąd pojawi się nie natychmiast. Niemniej warto zaznajomić się z obsługą debuggera :)

    0
  • #8 28 Cze 2012 09:26
    jolkajolka
    Poziom 12  

    O ranyy z tym for, to nie wiem jak mogłam nie zauważyć takiego banalnego błędu, aż nie mogę się nadziwić, że coś takiego napisałam i nie zauważyłam;P A debuggera jak się uruchamia/ustawia breakpointy/idzie do kolejnego stepu to wiem, tylko po prostu rzadko go używam. Postaram się zrobić poprawne sortowanie.

    0
  • #9 28 Cze 2012 16:28
    Dżyszla
    Poziom 42  

    Mały offtopic, ale: Nie martw się, zdarza się to najlepszym (w zasadzie też się sobie dziwię, czemu na to nie zwróciłem uwagi ;p). Sam także nieraz iterowałem pętlę od 0 do Count i zachodziłem w głowę, czemu nie działa ;p Ale w takich sytuacjach przydatny okazuje się właśnie debugger (wiedziałem, że na ostatnim przebiegu się wywala).

    0
  • #10 28 Cze 2012 21:29
    jolkajolka
    Poziom 12  

    ;)
    Ok, już napisałam poprawne sortowanie, ale to i tak nie koniec, bo niestety funkcja strcmp nie sprawdza się w moim tekście(są duże/małe litery)... Myślę, że trzeba napisać funkcję która działa podobnie, ale ignoruje wielkość liter i znaki interpunkcyjne. Aha i tu pytanie... w jaki sposób działa funkcja strcmp? Każda literka ma swój kod, ale gdybyśmy dodali sumę tych kodów w stringu i porównali z innym to wtedy nie porówna ich ona alfabetycznie(nie wiem czy dobrze tłumaczę o co mi chodzi;P). Jest jakiś sposób na to? Bo myślę, że zignorowanie wielkosci liter i innych znaków nie jest skomplikowane. Nie wiem jednak jak powinnam porównać te stringi(porównywać je literka po literce każdy z każdym?)

    0
  • #11 28 Cze 2012 21:55
    Dżyszla
    Poziom 42  

    Funkcja działa mniej więcej tak - brana jest różnica kodów ASCII pomiędzy pierwszymi znakami. Jeśli wynosi 0 - brana jest różnica kodów ASCII pomiędzy i+1 znakami (czyli do momentu, aż nie będzie 0 lub nie zostanie osiągnięty koniec).

    Jeśli chcesz ignorować wielkość (lub także poprawnie umieścić polskie znaki) musisz napisać własną funkcję najlepiej na tej samej zasadzie, lecz zamiast kodów ASCII nadasz własne wartości literom (funkcja switch/case - tu "tłumaczenie" literek na "wartość" to pole dla kolejnej funkcji ;) )

    Code:

    funkcja: pobierz_wartosc(znak)
    jeżeli znak
       'a','A': rezultat = 1;
       'ą','Ą': rezultat = 2;
       'b': rezultat = 3;
    koniec

    funkcja: porównaj(ciag1,ciag2)
    różnica = 0
    i = 0
    wykonaj
        różnica = pobierz_wartość(ciąg2[i]) - pobierz_wartość(ciąg1[i])
        zwiększ i
    do momentu, aż różnica <> 0 lub koniec
    zwróć różnica
    koniec


    Oczywiście funkcja określająca wartość może być znacznie prostsza, ale taka forma, jak zasugerowałem, dalej nieograniczone pole manewru.

    0
  • #12 28 Cze 2012 23:59
    Sam Sung
    Poziom 30  

    Do porównywania z ignorowaniem wielkości znaków służy strcasecmp, ewentualnie stricmp w zależności od biblioteki.
    A takich błędów jak wyżej nie ma sensu próbować szukać na oko, puszcza się pod debuggerem i się znajduje.

    0
  • #13 02 Lip 2012 20:56
    jolkajolka
    Poziom 12  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Napisałam te dwie funkcje. Funkcja value działa poprawnie, jednak z compare jest coś nie tak, bo string "I'm" ustawia na pierwszym miejscu po "Bd", reszte sortuje poprawnie...

    0
  • #14 02 Lip 2012 21:12
    Dżyszla
    Poziom 42  

    Troszkę niepotrzebnie wydaje mi się zamotane z tym dodatkowym sprawdzeniem pierwszych znaków. To powinno się odbyć wszystko na pętli do..while - byłoby czytelniejsze.

    Ale tak jak patrzę na kod, to nic nie dostrzegam niewłaściwego.... Ale pewnie znów jakiś szczegół przeoczam ;p Więc tylko powtórzę - debugger i sprawdzaj, jakie wartości są zwracane, które litery badane...

    Edycja: A czy przypadkiem warunek wykonania pętli nie powinien obejmować obu równocześnie przypadków ,a nie alternatywy? ;)

    0
  • #15 04 Lip 2012 09:50
    jolkajolka
    Poziom 12  

    Wklejam funkcje zczytwania wartości liter,porówywania i sortowania:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Tekst:
    I'm from clothespins,
    from Clorox and carbon-tetrachloride.
    but I'm from the dirt under the back porch.

    jest sortowany tak:
    from Clorox and carbon-tetrachloride.
    but I'm from the dirt under the back porch.
    I'm from clothespins,

    Mój debugger pisze, że(tekst w terminalu wyświetla się poziomo, nie w dwóch linijkach jak tu:
    [Thread debugging using libthread_db enabled]
    I'm from clothespins,
    from Clorox and carbon-tetrachloride.
    but I'm from the dirt under the back porch.
    Breakpoint 1, compare (string=0x804c180 "I'm from clothespins,\n", string2=0x804c1a0 "") at testlib.c:149
    149 int a,b,difference,i=0;
    (gdb) step
    153 a=value(string[i]);
    (gdb) step
    value (literka=73 'I') at testlib.c:130
    130 if(islower(literka))
    (gdb) step
    __ctype_b_loc () at ../include/ctype.h:27
    27 ../include/ctype.h: No such file or directory.
    in ../include/ctype.h

    .............
    Czyli coś jest nie tak z biblioteką <ctype.h>?

    0
  • #16 04 Lip 2012 18:09
    Dżyszla
    Poziom 42  

    Albo coś wycięłaś, albo funkcja compare zawiera ciut za dużo ;) Zakładam, że nie ma jej końca i początku następnej.

    Ponadto to co widać w debuggerze, to pusty string2 - chyba coś nie tak z indeksami lub z wczytywaniem ;)

    0
  • #17 04 Lip 2012 20:28
    jolkajolka
    Poziom 12  

    Dżyszla napisał:
    Albo coś wycięłaś, albo funkcja compare zawiera ciut za dużo ;) Zakładam, że nie ma jej końca i początku następnej.

    Ponadto to co widać w debuggerze, to pusty string2 - chyba coś nie tak z indeksami lub z wczytywaniem ;)


    Tak, po prostu wklejałam tylko fragment i nie zauważyłam, że nie wkleiłam adresu.
    Gdy robię coś takiego:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    gdy moj tekst:
    I'm from clothespins,
    from Clorox and carbon-tetrachloride.
    but I'm from the dirt under the back porch.
    and Emme is the best ende

    To wyświetla się: 105-105-105, a przecież wszystkie wyniki powinne mieć jednakowe znaki.... A wszystko mi się wyświetla poprawnie(tekst) więc myśle, że indeksowanie jest w porządku. Może to jednak compare...

    Kurcze, powinnam to zrobić i jestem już tak blisko a cały czas coś nie tak:(

    0
  • #19 04 Lip 2012 21:52
    jolkajolka
    Poziom 12  

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Dodano po 3 [minuty]:

    Czyli ma problem z czytaniem stringów..., ale gdy wyświetlam tekst
    :
    Kod: c
    Zaloguj się, aby zobaczyć kod


    To wyświetla się wszystko poprawnie...

    0
  • Pomocny post
    #20 04 Lip 2012 21:59
    Dżyszla
    Poziom 42  

    Dziwią mnie te pierwsze porównania - w kółko porównujesz ciąg pusty z "I'm from clothespins, "

    Następnie dwa sensowne i znów to samo... Coś nie tak ewidentnie.

    Wniosek 1: Funkcja porównująca jest ok. Parametry doń przekazywane - niebardzo.

    To jeszcze jedno... Zapisz wyświetlanie całej tablicy ze stringami na początku każdego przebiegu pętli przeszukującej w taki sposób:

    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Edycja: Chyba wyłapałem winowajcę - pętle w układzie for..do..while są źle zapisane. Powinnaś przeczesywać tablicę (for) tak długo (do..) aż nie będzie żadnej zamiany (..while). Zrobiłaś to w złej kolejności i wystąpienie zamiany powoduje ponowne obracanie tych samych indeksów. Czyli głównym jest do..while, a w każdym przebiegu musi wystąpić for bez żadnych szczególnych warunków na zakończenie.

    0
  • #21 04 Lip 2012 22:26
    jolkajolka
    Poziom 12  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    i działa:D:D, dzięki wielkie;)

    0