webForumDet fria alternativet

regexp eller likanande i C

C/C++

13 svar · 402 visningar · startad av Addeladde

Medlem sedan jan. 20013 406 inlägg
Frågan#1

Hej

hur gör man om man vill söka i ord som finns i en textfil om man t.ex.

ska kunna söka så här:

Sökning: B?ll
Resultat: Boll

Sökning: Sto?t?
Resultat: Stolts, Stortå

? markerar alltså var det kan vara en annan bokstav.

Några förslag?

Medlem sedan juni 200010 432 inlägg
#2

Jag antar att du vill ha '?' som joker i söksträngen? Eller menar du att även 'Båll' ska ge 'Boll' ? Isf måste du definiera hur många missar man kan ha och vilket fall som är basfall (Borde i det här fallet vara första bokstaven). Om det är så att du vill få att godyckligt tecken kan vara godtyckligt antal ggr fel, så blir det bara sökning på den första bokstaven som är relevant. ;) Så du bör vara på det klara med exakt hur du vill ha det.

Hur du än vill göra så är måste du dela in din textmassa i ord. Antingen plockar du dessa direkt från filen eller så läser du in filen i minnet och itererar dig igenom strängen och efter varje nullterminering + mellanslag (eller vad det nu är som delar orden från varandra), sätter du en pekare på varje ny förekomst av ord, skickar pekaren tillsammans med pekare till sökordet som argument till en funktion som går igenom varje tecken i ordet. Funktionen kan ju förslagsvis returnera '1' om den hittade matchning och då har du ju redan en pekare till det hittade ordet. Kommer ihåg att jag gjort nåt liknande och då var strchr() en bra hjälp i funktionen som kontrollerar enskilda tecken. Den här uppgiften är delikat för pekare och det bästa sättet att komma igång är att plita med papper och penna först :)

Det finns antagligen färdiga lib för det här, men inte som standardlib och är det en skoluppgift är det nog tänkt att du ska använda standardlib (enligt ANSI-C) och lösa problemen själv.

Medlem sedan jan. 20013 406 inlägg
#3

Ok tack för hjälpen

Det är en textfil med ord som är separerade på rader.
Man ska söka igenom filen och hitta de ord som man kan hitta om man byter ut ? mot någon bokstav.

Medlem sedan juni 200010 432 inlägg
#4

Okej. Då föreslår jag att du läser in filen i minnet genom att peta in varje ord i en array och sen kör en funktion som jag tipsade om (strchr()). Funktionen går att göra på 4-5 rader kod och det finns säkert lite exempel på strchr i din bok (som du har?) som du kan fundera kring.

Medlem sedan jan. 20013 406 inlägg
#5

Kan man läsa in hela svenska akademins ordlista i en array?

Medlem sedan maj 20002 993 inlägg
#6

Ramminnet lär räcka.

Medlem sedan jan. 20013 406 inlägg
#7

Detta är en början men det verkar inte fungera så bra

 while( feof( ordfil ) == 0 ){
     fgets(ord, listaLangd, ordfil);
     if(strlen(ord)==strlen(inOrd))
     {
       if(strcmp(inOrd, ord)==true){
         puts(ord);
       }
     }
   }
Medlem sedan juni 200010 432 inlägg
#8

Addeladde skrev:

Kan man läsa in hela svenska akademins ordlista i en array?

Kan och kan... frågan är om det är för stort för att bli effektivt. Men för sökfunktionen spelar det ingen roll om orden ligger i en array eller kvar i filen.

Detta är en början men det verkar inte fungera så bra

Nej. Till att börja med returnerar inte strcmp true, utan 0 om orden är exakt lika. Den lösningen ger förresten inte några möjliga alternativ som ?. Sen bör du nog tänka på att i C hanterar man snarare tecken än strängar, så om du ska plocka ut jokertecken måste du dissekera strängarna in i minsta tecken. Vidare är det skillnad på gemena och versaler så det är att föredra att göra allt lika med tolower innan man opererar på strängarna. Du kommer även behöva ett basfall, dvs att man söker på första bokstaven och sen sätter en pekare på den positionen, därefter är det bara att plocka nästa och sen nästa o.s.v...

Det är inte helt trivialt, men fullständigt lösbart :)

Medlem sedan jan. 20013 406 inlägg
#9

Supersvårt enligt min mening

Medlem sedan jan. 20013 406 inlägg
#10

Jag löste det, det var igentligen inte så svårt. strch() behövdes inte.

loopade igenom det inmatade ordet och kontrolledade det mot varje rad som inehöll lika många tecken och där tecknet inte vara ?

Medlem sedan juni 200010 432 inlägg
#11

Allt beror ju på vilka kriterier man har. Man kan ju tänka sig att man bara vill ge lite ledord i sin sökning och få upp flera förslag.. exempelvis 'Boll?' kan ju ge:

Boll
Bollkonstnär
Bollplank
Bollpåse

osv... Medans 'Bollp?' isf ger

Bollplank
Bollpåse

I det läget kan man inte gå efter lika antal tecken ;)

Men det är ju bra om du fått till en lösning som passar just dig :bire

Medlem sedan jan. 20013 406 inlägg
#12

Löst och klart inför labben!

Tack för hjälpen i alla fall PeW :bire

Medlem sedan juni 200010 432 inlägg
#13

Vassego ;)

Medlem sedan juli 2002581 inlägg
#14

Här är en enkel funktion som jämför strängar med avseende på * och ?

bool wildcmp(const char* s1, const char* s2)
{
    if (!*s1 || !*s2) return !*s1 and!*s2;
    if (*s1=='*' || *s2=='*') return wildcmp(s1,s2+1) or wildcmp(s1+1,s2+1) or wildcmp(s1+1,s2);
    if (*s1==*s2 or *s1=='?' or *s2=='?') return wildcmp(s1+1,s2+1);
    return false;
}
267 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
127 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)
118 ms — ändringar (db)