controleren op letter combinaties

Status
Niet open voor verdere reacties.

stykurgh

Gebruiker
Lid geworden
6 jul 2009
Berichten
715
hallo,

ik wil een string controleren op lettercombinaties. bijvoorbeeld als je "hallo" intypt bij een cin command dat hij dan gaat kijken en ziet dat h,a,l,l,o erin zitten maar ook ha,al,ll,lo en dat ook met 3 combi etc. en dan moet hij voor de A een 1 wegschrijven in een txt file en voor B een 2 etc. maar ik had dat zo gedaan:

found2=strin1.find("bc",c);
if (found2!=string::npos)
{
myfile1 << "31";
c+=1;}

C is een positie. alleen mijn vraag is kan dit niet makkelijker? want het is op deze manier nogal veel werk om dat allemaal te typen.

mvg

michel
 
h a l l o
ha al ll lo
hal all llo
hall allo

Het vinden van de lettercombinaties is niet zo heel lastig hoor:

[cpp]
string s("hallo");
for (int i = 1; i < s.length(); i++)
for (int j = 0; j <= s.length()-i; j++)
// s.substr(j, i) geeft nu de lettercombinaties
[/cpp]

Om vervolgens de juiste waardes om weg te schrijven te krijgen kan er door de string s.substr(j,i) geïtereerd worden en bij elk geldig karakter (a-z/A-Z) kan de startwaarde-1 genomen worden om de juiste waarde te verkrijgen.

[cpp]
int m = 0;
if (s[k] >= 'a' && s[k] <= 'z')
m = 'a'-1;
else if (s[k] >= 'A' && s[k] <= 'Z')
m = 'A'-1;
// s[k]-m geeft nu de juiste waarde (a/A = 1, b/B = 2, etc)
[/cpp]

Met het bovenstaande zou je wel tot een werkend geheel moeten komen. Succes.
 
.. is er een maximum aan de lengte van de combi?

ja denk iets van 24 ofzo. maximum aantal dat je in kan voeren.

en btw die code, werkt dat ook voor combinaties van 2? aa ofzo? dan geeft hij cker 11 als uitvoer?
heb het nog niet geprobeert. die ik denk ik vanavond even.

heel erg bedankt voor de reacties.

mvg

michel
 
ja denk iets van 24 ofzo. maximum aantal dat je in kan voeren.

en btw die code, werkt dat ook voor combinaties van 2? aa ofzo? dan geeft hij cker 11 als uitvoer?
heb het nog niet geprobeert. die ik denk ik vanavond even.

heel erg bedankt voor de reacties.

mvg

michel

... ik heb niets meer aan zo'n mooi stukje code toe te voegen .. :)
 
ja denk iets van 24 ofzo. maximum aantal dat je in kan voeren.

en btw die code, werkt dat ook voor combinaties van 2? aa ofzo? dan geeft hij cker 11 als uitvoer?
heb het nog niet geprobeert. die ik denk ik vanavond even.

Uit je post dacht ik te halen dat dit de bedoeling was (aa weg te schrijven als 11). Om "aa" te laten gelden als bijvoorbeeld 27 zal je een tabel moeten bijhouden. Het generen van de juiste waardes is hier niet zo'n probleem, maar je spreekt over zo enorm veel waardes dat dit eigenlijk niet te doen is.
 
hoe doe je dat dan met die tabel? ben nog niet super goed met c++. maak je dan gewoon een tabel en dan zet je daar de combinaties in met de waarden ofzo? en dan laat je die checken?
 
hoe doe je dat dan met die tabel? ben nog niet super goed met c++. maak je dan gewoon een tabel en dan zet je daar de combinaties in met de waarden ofzo? en dan laat je die checken?

Naast het feit dat het onbegonnen werk is om zo'n grote tabel bij te houden, had ik iets dieper moeten nadenken bij het posten van mijn reactie. Nu ik er nog eens naar kijk zie ik namelijk dat je de lettercombinaties als het 26-tallig stelsel moet zien en dat biedt ook meteen de mogelijkheid om de juiste waarde te verkrijgen (a-z = 1 t/m 26; aa-az = 27t/m52; etc)

Voor het omzetten zou je iets als het onderstaande kunnen gebruiken:

[cpp]
#include <cmath>
long long unsigned int base26_to_llui(const std::string &str)
{
long long unsigned ret_val = 0;
const unsigned int last = str.length()-1;
for (unsigned int i = 0; i < str.length(); i++)
if (isalpha(str))
ret_val += (long long unsigned int)(std::pow(26.0, (double)i) * (toupper(str[last-i])-'A'+1));
return ret_val;
}
[/cpp]

Bij de meeste woorden moet de bovenstaande gewoon werken, maar als de string te lang is kan de waarde buiten het bereik van het gebruikte datatype komen.

(ik heb de code getest, maar ik ben momenteel wel aardig gaar. Dus wellicht maak ik ergens een denkfout :p)

edit: slapen lukt nog niet echt, dus ik heb even een werkend voorbeeld geschreven:

[cpp]
#include <cstdlib>
#include <iostream>
#include <string>
#include <cmath>
#include <fstream>

long long unsigned int base26_to_llui(const std::string &str)
{
long long unsigned ret_val = 0;
const unsigned int last = str.length()-1;
for (unsigned int i = 0; i < str.length(); i++)
if (isalpha(str))
ret_val += (long long unsigned int)(std::pow(26.0, (double)i) * (toupper(str[last-i])-'A'+1));
return ret_val;
}

int main()
{
std::string str("hallo");
std::ofstream out("d:\\out.txt");
for (unsigned int i = 1; i < str.length(); i++)
{
for (unsigned int j = 0; j <= str.length()-i; j++)
{
std::string temp(str.substr(j, i));
std::cout << temp << ' ' << base26_to_llui(temp) << '\n';
out << base26_to_llui(temp) << ' ';
}
}
out.close();
system("PAUSE");
return EXIT_SUCCESS;
}[/cpp]
 
Laatst bewerkt:
heel erg bedankt :D hij werkt perfect. zou je misschien een beetje kunnen uitleggen wat het allemaal doet want ik snap het nog niet allemaal zo goed. en dan kan ik er nog wat dingen in aanpassen.


in ieder geval heel erg bedankt voor de code!

mvg

michel

edit: ik snap dat eerste stuk niet. die zorgt voor de waarden toch?
 
Laatst bewerkt:
heel erg bedankt :D hij werkt perfect. zou je misschien een beetje kunnen uitleggen wat het allemaal doet want ik snap het nog niet allemaal zo goed. en dan kan ik er nog wat dingen in aanpassen.

edit: ik snap dat eerste stuk niet. die zorgt voor de waarden toch?

[cpp]
long long unsigned int base26_to_llui(const std::string &str)
{
long long unsigned ret_val = 0;
const unsigned int last = str.length()-1;
for (unsigned int i = 0; i < str.length(); i++)
if (isalpha(str))
ret_val += (long long unsigned int)(std::pow(26.0, (double)i) * (toupper(str[last-i])-'A'+1));
return ret_val;
}
[/cpp]

hier staat eigenlijk gewoon:

ret += 26^bitpositie*plaats_in_alfabet; // bitpositie gaat van rechts naar links, dus: 3 2 1 0; hij begint dan ook met de meest rechtste waarde

AA -> 26^1*1 + 26^0*1 -> 26 + 1 = 27
AB -> 26^1*1 + 26^0*2 -> 26 + 2 = 28
AZ -> 26^1*1 + 26^0*26 -> 26 + 26 = 52
BA -> 26^1*2 + 26^0*1 -> 52 + 1 = 53
AAA -> 26^2*1 + 26^1*1 + 26^0*1 -> 676 + 26 + 1 = 703

Als je het nog niet helemaal begrijpt dan hoop ik dat iemand anders het je kan uitleggen, ik ga zo feesten en daar zal ik morgen in elk geval nog zeker last van hebben. :p
 
ik snap het wel een beetje :D. snap alleen niet hoe je er op komt :P maargoed ik ben ook nog maar net bezig met c++ dus komt vast nog wel. ik had nog een kleine vraag. waarom gebruik je niet "using namespace std;" ?

heel erg bedankt voor de code! werkt perfect!

mvg

michel
 
ik had nog een kleine vraag. waarom gebruik je niet "using namespace std;" ?

Bij de voorbeelden die hier gepost worden maakt het eigenlijk niks uit, maar bij grotere projecten kan het wel problemen opleveren. Daarom schrijf ik het meestal gewoon volledig.

heel erg bedankt voor de code! werkt perfect!

Alleen heb ik wel het verkeerde return type gebruikt ("int" vergeten te schrijven) bij de functie base26_to_llui, dat hoort eigenlijk ook gewoon een long long unsigned int zijn.
 
Laatst bewerkt:
oke. hij deed het wel gewoon ondanks dat dat int er niet bij stond :P.

heb het er even bij gezet ondertussen. heel erg bedankt voor je hulp :thumb:

mvg

Michel
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan