Permalänk
Medlem

Ordräkning i C [noob]

Har precis börjat med C och har kört fast lite nu.
Det handlar om att jag ska räkna hur många av varje ord som jag har. Så som jag har det nu så finns orden representerade med hjälp av en struct med chars, så jag har t.ex ord[1].bokstav[2], ord[1].bokstav[3] osv. Jag fick tipset att jag borde nullterminera alla ord, så det kommer jag antagligen lägga in.

Frågan är nu, hur ska jag bära mig åt för att utföra räkningen? Min tanke var att om jag sorterar alla ord i bokstavsordning så kan jag gå igenom alla ord, och så länge nästkommande ord inte skiljer sig från det som kom innan så räknar jag upp. Om det skiljer sig så nollställer jag räkningen och sparar undan resultatet.

Men att skriva en sån sorteringsalgoritm känns väldigt jobbigt iom att allt är representerat med chars.

Jag fick tipset om att använda qsort för att sortera, så jag googlade lite på det och kom fram till denna sidan http://www.cplusplus.com/reference/clibrary/cstdlib/qsort.htm... .
(iofs c++ sida, men vad jag förstått ska det fungera i C också)

Men jag fattar inte riktigt hur det fungerar ändå i mitt fall med den strukturen jag har med ord[nr].bokstav[nr]

Blir det ngt i stil med

qsort(ord.bokstav, ord.antalbokstäver, 1, compare);

Måste jag isåfall skriva en egen compare? Hur bör den se ut isåfall?
Är noob på C så det uppskattas med lite utförlig förklaring. Och självklart om ni tycker jag är helt ute och cyklar och tror att jag kan fixa detta enklare på annat sätt så shoot.

Visa signatur

Du är min fiende tills motsatsen är bevisad, och bevisbördan ligger hos dig.

Permalänk
Avstängd

På sid 160 i boken "The C programming Language" av Kernighan och Richie, den svenska upplagan så står det så här:

Antag att vi vill hantera det mera generalla problemet att räkna förekomster av alla ord i en inmatning. Eftersom listan av ord ej är känd i förväg, kan vi inte bekvämt sortera den och använda en binär sökning. Vi kan inte heller göra en linjär sökning för varje ord som det anländer, ... bla bla etc etc

Du kanske hittar en intressant lösning där? Jag antar att du har den boken, då det är C-bibeln. Det är mycket lärorikt att se andra lösningar.

Permalänk
Medlem

Hmm, har ingen kompilator så jag kan inte testa min kod men den kan väl i alal fall peka dig i rätt riktning... Orkar inte kommentera hela nu men den sorterar orden medan man matar in dom, alltså är ordlistan alltid sorterad... Den lägger inte heller in dubbletter utan ökar då bara "count" i Word-structen... nåväl fråga gärna om något är konstigt...

struct Word{ char word[100]; int count; }; void setWord(char* set, char* to){ int n; for(n = 0; to[n] != '\\0'; n++){ set[n] = to[n]; } set[n] = '\\0'; } void addWord(char* theWord, Word* theWords, int* numberOfWords){ int wordCheck = 0; int letterCheck = 0; while(1){ if(wordCheck >= numberOfWords){ setWord(theWords[wordCheck].word, theWord); theWords[wordCheck].count = 1; numberOfWords++; break; }else if((int)theWords[wordCheck].word[letterCheck] < (int)theWord[letterCheck]){ wordCheck++; letterCheck = 0; }else if((int)theWords[wordCheck].word[letterCheck] > (int)theWord[letterCheck]){ numberOfWords++; for(int n = numberOfWords; n > wordCheck; n--){ theWords[n] = theWords[n-1]; } setWord(theWords[wordCheck].word, theWord); theWords[wordCheck].count = 1; break; }else if(theWords[wordCheck].word[letterCheck] == theWord[letterCheck]){ if(theWord[letterCheck] == '\\0'){ theWords[wordCheck].count++; break; }else{ letterCheck++; } } } } int main(){ char text[5000] = "In this paper I shall defend a Humean theory of motivation. But first I should like to examine some of the standard criticisms of this theory and some alternative views that are currently in favour. Both in the Treatise and the Enauirv Hume maintains that reason alone never motivates action but always requires the cooperation of some separate, and separately identifiable desire-factor in order to bring about action."; char currentWord[100]; int currentWordAt = 0; Word words[1000]; int numberOfWords = 0; for(int n = 0; text[n] != '\\0'; n++){ if((int)text[n] >= 97 && (int)text[n] <= 122){ currentWord[currentWordAt] = text[n]; currentWordAt++; }else if((int)text[n] >= 65 && (int)text[n] <= 90){ currentWord[currentWordAt] = (char)((int)text[n]+32); currentWordAt++; }else if(currentWordAt > 0){ currentWord[currentWordAt] = '\\0'; addWord(currentWord, words, numberOfWords); currentWordAt = 0; } } if(currentWordAt > 0){ currentWord[currentWordAt] = '\\0'; addWord(currentWord, words, numberOfWords); } for(int n = 0; n < numberOfWords; n++){ cout << "Word: " << words[n].word << ", Occurrence: " << words[n].count << endl; } return 0; }

Permalänk
Medlem

Om det går bra med c++ så är väl den enklaste lösningen en map, t.ex.
map<string, unsigned int> words;
och sen använder man orden som index i map:en, alltså: ++words[ord].

Skulle ju kunna göra något liknande i ren C, genom att implementera en hashmap eller dylikt. Annars är ju sortering en bra lösning.

Visa signatur

Intel Core i7-3770K | NVIDIA Geforce GTX 980 | 16 GB DDR3 | DELL P2415Q | DELL U2711 | DELL U2410