Det är ju lite konstigt... prog. lösning

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Icecap
Inlägg: 26423
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Det är ju lite konstigt... prog. lösning

Inlägg av Icecap »

För en del år sedan (18 mars 2015) hade jag en tråd (viewtopic.php?t=76727) där jag funderade på hur jag kunde skapa 2 tabeller ur en enkel "tabell" data.

Inkommande kommando-sträng kommer via en seriell port och vid '\n' kallas kommando-dekoderen.
Exempel: "SET TIME 12:34:56\n".

Det rör sig om text-kommandon i en sträng där de olika ord i ett kommando kan definieras i en "tabell" och det sedan automatisk skapas 2 tabeller:
* 1 tabell med kodorden i textformat. Tänk const char* Comm_Words["SET", "GET", "TIME", "DATE" osv.]
* 1 tabell med namngivna enum. Tänk enum(Index_SET, Index_GET, Index_TIME, Index_DATE osv).

Att skapa dessa tabeller manuellt är i grunden enkelt - men när det blir tillägg, justeringar eller liknande, VILL det på något tidpunkt bli ett fel så att de 2 tabeller inte passar ihop.

Nu - i mitt nuvarande jobb - har jag återigen haft STOR bruk av detta, denna gång med 60 olika kommando-ord samt kommandon med mellan 1 och 4 kommandoord samt '?' eller värden efter.

Så tack till alla som svarade i den tråd och speciellt till johano vars ide jag har använd - och återanvänd - till detta.

Orsaken är att jag inte har något problem med att hitta kommando-orden i textsträngen, jag kan enkelt jämföra det inkommande ord med tabellen med orden i (skriver orden alfabetisk för snabbast möjlig steg till nästa kommando-ord vid mismatch), men som jag har sett i detta nuvarande projekt SKER det stavfel när man ska skriva samma ord fler gångar.

Den förra programmör har bokstavligen testat de olika kombinationer vid att skriva en strncmp(<kommando-ord>, <pekare till inkommande text>, strlen(kommando-ord>)==0 upprepande gångar.
Detta har svald så mycket flash-minne så att vi närmar oss ett kritisk punkt. I svaren på dessa kommandon skrivs kommando-orden IGEN.

Numera har jag kolla på indexeringen i kommando-ord kedjan och då återanvänder jag de kommando-ord som redan finns till att skapa svaren.
Ex: Comm_Words[Index_SET] + " " + Comm_Words[Index_TIME] + ": " + tiden i ascii.

Jag inbillar mig även att vid att omvandla ett ord till dess index i tabellen kan jag spara lite tid och vid att bara ha texterna ett enda ställe sparar jag en del plats.
mounte
Inlägg: 207
Blev medlem: 14 november 2010, 13:15:00
Ort: Sandviken

Re: Det är ju lite konstigt... prog. lösning

Inlägg av mounte »

Eftersom du har listan över keywords redan så kan du använda "perfect hash"
Du skapar en enklare form av hash-funktion som säkerställer att det inte förekommer kollisoner bland de keywords du använder när du skapar funktionen.
Du får då en funktion som tar en array av uint8 eller char eller vad du nu använder och som hystar ur sig en hash som du sen kan använda till att indexera i din array.
Om du måste ha index från 0 till n-1 så får du eventuellt använda en lookup som tar hash_0 --> 0, hash_1 --> 1 osv.

Du kan använda vilken hash-funktion som helst egentligen men förslaget till "perfect hash" är för att du oftast får en enkel funtion med ett antal boolska operationer bara och kräver inte en massa beroenden, men sha, md5, ibland crc fungerar också.

Då slipper du alla sträng-jämförelser och kan istället antingen direkt använda index, eller index via lookup, eller jämföra mot hashvärdet direkt.
Användarvisningsbild
Icecap
Inlägg: 26423
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Det är ju lite konstigt... prog. lösning

Inlägg av Icecap »

Hmm - det kan vara en lösning också.

Just nu har jag löst det med att hitta inkommande kommando-ord och sedan leta igenom "kända ord"-tabellen snabbt, om inte första bokstaven matchar skippas till nästa.
Om de matchar kollas längden som ska vara identisk och om DET också matchar kollats tecknen mot varandra.

Ska fundera lite på hash, nog mest på hur jag kan implementera det så att hashningen utförs under kompileringen och resultatet sparas i ROM.
Ska det hashas externt blir enkelheten kraftigt lidande.
Det finns inte RAM nog till att utföra hashningen vid initialiseringen.

Just nu har jag förbättrat våldsamt på det befintliga - men det betyder ju inte att det inte kan bli bättre.

Det finns dock en signifikant del problem i resten av projektet som ska fixas innan jag får tid till detta.
Skriv svar