Forum » Programiranje » [C++] Ponavljanje črk v stringu
[C++] Ponavljanje črk v stringu
xtrEeme ::
Lep pozdrav.
Ukvarjam se z funkcijo ki sprejme string in v njem poišče katere črke se ponavljajo in koliko krat. Ustavil se mi je nekje tukaj:
Torej vsak znak v podanem stringu sem shranil v polje char c, v drugem polju char Alphabet imam črke angleške abecede. Sedaj nevem kako bi z zanko preveril ujemanja v teh dveh poljih in izpisal tiste ki se ponavljajo več kot enkrat. Ustvaril sem tudi strukturo v katero nameravam shraniti rezultate, vendar mi ne uspe. Kak predlog?
p.s. Ne gre za nobeno nalogo za faks, programiram preprosto zaradi hobija in osebnega interesa
Ukvarjam se z funkcijo ki sprejme string in v njem poišče katere črke se ponavljajo in koliko krat. Ustavil se mi je nekje tukaj:
#include <iostream> #include <string> using namespace std; int main() { struct letter { char letter; int count; }; string x; char Alphabet[] = {'a','b','c','d','e','f','g','h','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; getline(cin, x); char c[x.length()]; int length = x.length(); int countC=0; for(int i=0;i<length;i++) { c[i] = x[i]; } for(unsigned int b=0;b<25;b++) { for(unsigned int e=0; e<x.length(); e++) { } } return 0; }
Torej vsak znak v podanem stringu sem shranil v polje char c, v drugem polju char Alphabet imam črke angleške abecede. Sedaj nevem kako bi z zanko preveril ujemanja v teh dveh poljih in izpisal tiste ki se ponavljajo več kot enkrat. Ustvaril sem tudi strukturo v katero nameravam shraniti rezultate, vendar mi ne uspe. Kak predlog?
p.s. Ne gre za nobeno nalogo za faks, programiram preprosto zaradi hobija in osebnega interesa
b00mer ::
Em
Gres skozi tabelo Alphabet, vzames prvo crko in preverjas kolikokrat se pojavi v nizu in vsakic povecas stevec.
Izpises..stevec na nulo.
Gres skozi tabelo Alphabet, vzames prvo crko in preverjas kolikokrat se pojavi v nizu in vsakic povecas stevec.
Izpises..stevec na nulo.
boogie_xlr ::
Abecede ne potrebuješ: poglej si ASCII kodiranje; vsak znak ima svojo vrednost.
Potrebuješ pa polje, v katerega bos shranjeval števce za vsako črko.
Potem lahko v eni while zanki prešteješ črke za celoten vhod.
Potrebuješ pa polje, v katerega bos shranjeval števce za vsako črko.
Potem lahko v eni while zanki prešteješ črke za celoten vhod.
xtrEeme ::
Kako shranjujem števce za vsako črko posebej to mi ni jasno. Mi lahko en malo nakaže praktično?
Zgodovina sprememb…
- spremenil: xtrEeme ()
boogie_xlr ::
Narediš polje integerjev
ker ima 'a' po ascii tabeli vrednost 97, enostavno odstejes 97 in dobis 0
na tem mestu v polju stevcev stejes a-je, zato ga povecas za 1
int stevci[25];in inicializiraš celotno polje na 0
ker ima 'a' po ascii tabeli vrednost 97, enostavno odstejes 97 in dobis 0
na tem mestu v polju stevcev stejes a-je, zato ga povecas za 1
znak = 'a'; stevci[znak - 97]++;
xtrEeme ::
Hvala, zdaj mi je jasno za kaj se gre.
Ali lahko celotno polje inicializiram na 0 z memset funkcijo?
npr. tako ?
Ali lahko celotno polje inicializiram na 0 z memset funkcijo?
npr. tako ?
int stevci[25]; memset(stevci,0,25);
boogie_xlr ::
lahko
vendar pazi, sizeof(stevci) ni 25! ampak 25 * sizeof(int)
memset(stevci,0,sizeof(stevci));
vendar pazi, sizeof(stevci) ni 25! ampak 25 * sizeof(int)
mallard ::
Mal bi tvojo kodo pokomentiral:
Tudi ni nobene potrebe po memset-u. Polje se napolni z ničlami če uporabiš prazen initializer:
Jaz bi na tvojem mestu za števec uporabil polje, ki je dovolj veliko, da zajame vse možne vrednosti tipa char - 256 znakov, torej. Tako ti ni treba gledat in skrbet kaj točno imaš v stringu (vejice, pike, številke), ampak se preprosto sprehodiš čez in prištevaš vrednosti za vsak znak posebej. En haklc - char je bodisi predznačen ali ne-predznačen tip, odvisno od implementacije jezika, zato ga ne moreš meni nič tebi nič uporabit za indeksiranje v polje, ampak ga cast-aš v unsigned char, recimo. Nekej takega bi jaz napisal:
To seveda preverja samo male črke, velike imajo drugo vrednost. To pa lahko nardiš za vajo.
Pa še - ne se navadit na using namespace std;. Za take vaje je v redu, pri kakšenm resnem delu se pa uporablja kvalificirana imena. Srečno.
#include <iostream> #include <string> using namespace std; int main() { // Razen če veš, da jih rabiš, se izogibaj lokalno definiranim tipom. // Tak tip ni viden in ni uporaben zunaj funkcije main. Definiraj ga // globalno. struct letter { char letter; int count; }; string x; // Namesto polja bi jaz uporabil string literal. //char Alphabet[] = {'a','b','c','d','e','f','g','h','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; const char* Alphabet = "abcdefghijklmnopqrstuvwxyz"; // String literal je v bistvu tudi polje, je pa razliko od lokalnega polja statično initiliziran (ob zagonu programa, // še preden se zažene main). Kazalec Alphabet kaže nanj, indeksiranje pa ostane enake. Pa če ne drugega, je manj za // pisat: getline(cin, x); // To pa v standardnem C++ ni dovoljeno. Dimenzija polja mora bit znana med prevajanjem. Sledeča vrstica se prevede // ker ima tvoj prevajalnik nestandardno razširitev jezika. char c[x.length()]; // Poleg tega pa nima smisla alocirat polje samo zato, da prekopiraš vsebino string objekta vanj. // Lahko preprosto delaš na x objektu, saj podpira indeksiranje z []. int length = x.length(); int countC=0; for(int i=0;i<length;i++) { c[i] = x[i]; } for(unsigned int b=0;b<25;b++) { for(unsigned int e=0; e<x.length(); e++) { } } return 0; }
Tudi ni nobene potrebe po memset-u. Polje se napolni z ničlami če uporabiš prazen initializer:
char arr[42] = {};
Jaz bi na tvojem mestu za števec uporabil polje, ki je dovolj veliko, da zajame vse možne vrednosti tipa char - 256 znakov, torej. Tako ti ni treba gledat in skrbet kaj točno imaš v stringu (vejice, pike, številke), ampak se preprosto sprehodiš čez in prištevaš vrednosti za vsak znak posebej. En haklc - char je bodisi predznačen ali ne-predznačen tip, odvisno od implementacije jezika, zato ga ne moreš meni nič tebi nič uporabit za indeksiranje v polje, ampak ga cast-aš v unsigned char, recimo. Nekej takega bi jaz napisal:
#include <iostream> #include <string> using namespace std; const char* abc = "abcdefghijklmnopqrstuvwxyz"; int main() { string s; getline(cin, s); int counters[256] = {}; for (char c : s) { unsigned char uc = c; ++counters[uc]; } // Izpiši znake, ki se pojavijo več kot enkrat // zanimajo nas samo črke for (int i = 0; i < 26; ++i) { unsigned char uc = abc[i]; int n = counters[uc]; if ( n > 1) cout << char(uc) << ": " << n << '\n'; } }
To seveda preverja samo male črke, velike imajo drugo vrednost. To pa lahko nardiš za vajo.
Pa še - ne se navadit na using namespace std;. Za take vaje je v redu, pri kakšenm resnem delu se pa uporablja kvalificirana imena. Srečno.
xtrEeme ::
JanK ::
Ce se ze gremo c++, bi uporabil dinamicno strukturo "map" in iteratorje:
#include <iostream> #include <string> #include <map> int main() { std::string s; std::getline(std::cin, s); std::map<char, unsigned> count; for( std::string::const_iterator p = s.begin(); p != s.end(); ++count[*p++] ); for( std::map<char, unsigned>::const_iterator p = count.begin(); p != count.end(); ++p ){ if( p->second > 1 ){ std::cout << p->first << ": " << p->second << std::endl; } } }
"Think about how stupid the average person is,
then realize that 50% are stupider than that"
-George Carlin
then realize that 50% are stupider than that"
-George Carlin
darkkk ::
Mah ne znam brat. Drgač pa sortiraj niz pa preštej :)
Zgodovina sprememb…
- spremenil: darkkk ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | python-pomoč pri nalogi z niziOddelek: Programiranje | 1555 (1253) | galu |
» | [javaScript] Preverjanje formata zapisa EMŠOOddelek: Programiranje | 2962 (2582) | win64 |
» | java mali problem (začetnik)Oddelek: Programiranje | 2443 (2186) | ozbolt |
» | C++ in števkeOddelek: Programiranje | 1323 (1130) | Tutankhamun |
» | malo pomočiOddelek: Programiranje | 1073 (907) | ERGY |