» »

[C] Sortiranje preštetih črk

[C] Sortiranje preštetih črk

N-E-O ::

Moja naloga je, da iz neke datoteke preštejem črke (veliko in malo se smatra za enako) in v programu izpišem v padajočem vrstnem redu število njihovih ponavljanj.
Večino programa imam že napisanega ( Tukaj je koda). V komentarjih sem napisal, česar ne znam.

Prosim za kakšen namig ali dele rešitev. LP
Follow the white rabbit.

Backup22 ::

Kaj pa če bi najprej preštel koliko a-jev je in to shranil v neko polje[0]. Potem prešteješ A-je in shraniš v polje[1]. Potem prešteješ b-je in shraniš v polje[2].... prešteješ z-je in shraniš v polje[i]. To delaš v dveh zankah. Zunanja določi črko, notranja pa v if stavku inkrementira nek števec, ki ga ob koncu datoteke shrani v polje. Verjetno metoda ni najbolj optimalna, je pa razumljiva in narejena po kmečki logiki...
//

Genetic ::

za int ascii[] polje je dovolj, da je veliko toliko, kot je crk: char length = 'z'-'a'+1;
ascii[0] povecas, ko je prebrani znak 'a' ali 'A', ... ascii[c-'a'] ++;

Za sortiranje ustvaris novo polje, ki bo vsebovalo indexe na ascii polje:
char sortedIndexes[], kjer je dolzina zopet length;
in ga napolnis s stevili od 0 do length-1:
for (i...) sortedIndexes[i] = i;

V sortedIndexes[0] bo po sortiranju index tiste crke iz ascii polja, ki ima najvec znakov (ce je 'e'jev najvec, potem bo sortedIndexes[0] == 4 (5. crka je 'e')

Funkciji qsort dodas kot parameter tudi pointer na funkcijo, ki primerja dva elementa med sabo in vrne vrednosti -1(prvi<drugi), 0(prvi == drugi), 1(prvi>drugi)

int primerjaj_po_stevilu_znakov_padajoce(const void* prvi, const void* drugi)
{
    const char* cprvi = (const char*) prvi;
    const char* cdrugi = (const char *) drugi;
    int prvi_znakov = ascii[*cprvi];
    int drugi_znakov = ascii[*cdrugi];
    /* ker sortiramo padajoce, vrnemo -1, ce prvi>drugi in vice versa */
    if (prvi_znakov < drugi_znakov)
      return 1;
    else if (prvi_znakov > drugi_znakov)
      return -1;
    else
      return 0;
}


Sedaj sortiramo polje sortedIndexes

qsort(sortedIndexes, length, sizeof (byte), primerjaj_po_stevilu_znakov_padajoce);

in izpisemo znake in njihove pogostosti:

for (i=0; i<length; ++i)
{
printf("%c - %d\n",sortedIndexes[i]+'a',ascii[sortedIndexes[i]]);
}

Zgodovina sprememb…

  • spremenil: Genetic ()

N-E-O ::

Sem bolj začetnik v programiranju, zgornji opis je vsaj zaenkrat še malo zahteven zame za razumet.
Poskušal sem narediti po tvojem opisu: takole
Pa mi javi napake. Predvsem ne razumem tiste funkcije, ki primerja vrednosti (npr, razlika med const char* cprvi in (const char*) prvi). Pa nasploh s kazalci imam še težave. A prav razumem, da morajo elementi polja sortedIndexes[26] kazati na elemente ascii[26]? Kako se to napiše v c-ju?

Hvala.
Follow the white rabbit.

Genetic ::

Namesto
qsort(sortedIndexes, 26, 4, primerjaj_po_stevilu_znakov_padajoce);

uporabi
qsort(sortedIndexes, 26, sizeof(char), primerjaj_po_stevilu_znakov_padajoce);

Glej, qsort je zelo splosna funkcija, ki dela nad podano tabelo. V tabeli imamo lahko poljuben tip,v nasem primeru je tip char (1 byte).
Ker imamo tabelo poljubne dolzine in poljubnega tipa, moramo te podatke posredovati funkciji qsort. V drugi parameter damo dolzino polja (26), v tretji parameter pa damo dolzino tipa tabele v byteih (ti si podal 4, kar velja za int, mi pa imamo tabelo sortedIndexes tipa char, kar je obicajno 1 byte - sizeof (ime_tipa) vrne velikost tipa v byteih).
Kjer imamo poljubne tipe, imamo tudi razlicne nacine primerjanja. Zato podamo funkciji qsort tudi kazalec na funkcijo, ki je zadolzena za primerjanje. Ker mora biti ta funkcija cimbolj splosna, ima vhodne parametre kazalce na void (void*). Kazalec na bilokateri tip lahko pretvoris v void*, in ce ves, kateri tip neki void* kazalec predstavlja, lahko naredis tudi obratno pretvorbo.
Zato ima nasa funkcija za primerjanje taksno obliko.
Ker vemo, da to funkcijo uporablja funkcija qsort nad tabelo tipa char, vemo, da lahko pretvorimo void * prvi in void * drugi v kazalca tipa char:
const char* char_prvi = (const char*)prvi; // tej operaciji se rece casting - pretvorba: kazalec na void (prvi) pretvorimo v kazalec na char (char_prvi)

Genetic ::

Sorry, en popravek. Nisem videl da imas ti deklarirano sortedIndexes kot
int sortedIndexes[26];

To pomeni, da moras v funkciji primerjanja castati iz void* v int*:
const int *int_prvi = (const int*) prvi; //etc

Pa tudi v funkciji qsort pustis tretji parameter na 4 (int je velik 4b - ali pa das noter sizeof(int))

BigBoobs ::

Hy.

Jaz sem tudi bolj nov in me muci z delo z napravami pa rabim nek nasvet.

Napravo odprem, lepo ja, recimo disketnik.

Aja, ja, to imam za solo, ne prosim da mi resite, samo za majhno pomoc.

Namrec napravo odprem, to je disketnik. Sedaj pa ne vem kako se naj lotim da mi prebere z diskete in napise vsebino v console, kaj se nahaja na disketi.

z datotekami nimam nekih tezav. Ker je v linuxu vse datoteka se po moje obnasa nekaj enakega.

Nemorem pa nikakor prebrat, pa ce moram narediti nekako na enak nacin da ko bere da prebere do konca, ce obstaja kak "EOF" oz. ce ga lahko kako uporabim, da bi mi prebralo dokler ne pride do konca ali dam kar null? Ker sem nekak probal, vendar mi nikakor ne uspe.


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[C] LPC1343 - UART - AT commands

Oddelek: Programiranje
91016 (906) JanezovJanez
»

[C++] Naloga seznam

Oddelek: Programiranje
223088 (2363) Matic1911
»

[C] struct in int[] (strani: 1 2 )

Oddelek: Programiranje
656744 (5817) MrBrdo
»

strcpy reče segmatation fault

Oddelek: Programiranje
101425 (1376) MasterMind
»

c++ datoteke

Oddelek: Programiranje
463819 (3308) Vesoljc

Več podobnih tem