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 0ker 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 | 1592 (1290) | galu |
» | [javaScript] Preverjanje formata zapisa EMŠOOddelek: Programiranje | 3023 (2643) | win64 |
» | java mali problem (začetnik)Oddelek: Programiranje | 2499 (2242) | ozbolt |
» | C++ in števkeOddelek: Programiranje | 1355 (1162) | Tutankhamun |
» | malo pomočiOddelek: Programiranje | 1092 (926) | ERGY |