Forum » Programiranje » [C++] Brisanje znaka iz stringa
[C++] Brisanje znaka iz stringa
black ice ::
Mi ve kdo pomagati pri brisanju vejic iz stringa? Funkcija mi namreč izbriše cel string in po dolgotrajnem buljenju v ekran ne najdem vzroka zakaj.
//============================================================================ // Name : 1.cpp // Author : // Version : // Copyright : // Description : //============================================================================ #include <iostream> #include <string> #include <ctype.h> using namespace std; double povprecjeZnakov(string besedilo) { double st_znakov = 0, st_vrstic = 0; double povprecje; for (int i = 0; i < besedilo.length(); i++) { if (isprint(besedilo[i])) st_znakov++; else if ((besedilo[i] == '\n') || (besedilo[i] == '\r\n') ) st_vrstic++; } povprecje = (st_znakov / st_vrstic); return povprecje; } int prestejBesede(string besedilo) { int stevec = 0; //gremo skozi celoten string in primerjamo ce je kateri izmed znakov enak ' ' ali '\n' for (int i = 0; i < besedilo.length(); i++) { if ((besedilo[i] == ' ')|| (besedilo[i] == '\n') && (besedilo[i + 1] != ' ')) stevec++; } return stevec; } //Funkcija presteje kolikokrat se znaki iz prvega stringa pojavijo v drugem stringu //VHOD:stringa za primerjavo, polje stevcev //IZHOD:celostevilsko stevilo znakov int prestejPojavitve(string prvi, string drugi) { int stevec = 0; for (int i = 0; i < prvi.length(); i++) { //pretvorimo oba stringa v male crke prvi[i] = tolower(prvi[i]); drugi[i] = tolower(drugi[i]); for (int j = 0; j < drugi.length(); j++) { if (prvi[i] == drugi[j]) stevec++; } } return stevec; } string izbrisiVejice(string besedilo) { string nov; for (int i = 0; i < besedilo.length(); i++) { if (besedilo[i] == ',') nov[i] = ' '; else nov[i] = besedilo[i]; } return nov; } void zamenjajStevilke(string besedilo) { for (int i = 0; i < besedilo.length(); i++) { if (isdigit(besedilo[i])) { besedilo.erase(i, 1); besedilo.insert(i, "?"); } } cout << besedilo; } int main() { string besedilo; string vrstica; string ime = "ime"; int vrstic = 10; int izbira; do { cout << endl; cout << "Meni:" << endl; cout << "*------------------------------------------------------------*" << endl; cout << "|(1) - Vnos besedila |" << endl; cout << "|(2) - Izpis besedila |" << endl; cout << "|(3) - Povprecno stevilo znakov v vrstici |" << endl; cout << "|(4) - Stetje besed |" << endl; cout << "|(5) - Stetje stevila pojavitev znakov, ki so v " << ime << " |" << endl; cout << "|(6) - Izbris vejic |" << endl; cout << "|(7) - Zamenjava stevilk z '?' |" << endl; cout << "|(0) - Izhod |" << endl; cout << "*------------------------------------------------------------*" << endl; cout << "izbira: "; cin >> izbira; cout << endl; switch (izbira) //možnosti menija in klici funkcij { case 1: { cout << "Vnesi " << vrstic << " vrstic besedila:" << endl; cout << "------------------------------------" << endl; for (int i = 0; i <= vrstic; i++) { getline(cin, vrstica); besedilo.append(vrstica + '\n'); } break; } case 2: { cout << besedilo << endl; break; } case 3: { cout << "Povprecno stevilo znakov v vrstici: " << povprecjeZnakov(besedilo) << endl; break; } case 4: { cout << "Stevilo besed v tekstu: " << prestejBesede(besedilo) << endl; break; } case 5: { cout << "Znaki v " << ime << " se v besedilu pojavijo " << prestejPojavitve(ime, besedilo) << "-krat" << endl; break; } case 6: { cout << izbrisiVejice(besedilo); break; } case 7: { zamenjajStevilke(besedilo); break; } case 0: { return 0; } } } while (izbira != 0); return 0; }
Mesar ::
Poskusi tole..
Pa ZS maš
string izbrisiVejice(string content) { for ( int i = 0; i < content.length(); i++) { if (content[i] ==',') { content.replace(i, 1, ""); i--; } } return content; }
Pa ZS maš
Your turn to burn!
darkkk ::
funkcija bi ti morala usut program(če je kaj pravice na svetu)
Namreč string nov je prazen, ti bi pa kar na i-to mesto dostopal. Poleg tega tvoja koda ne briše vejic ampak jih zamenjuje s presledki.
Kakorkoli:
Ps, če moraš na stringu samem naredit tole, potem funkcija z referenco in uporabljaš find ter replace.
Namreč string nov je prazen, ti bi pa kar na i-to mesto dostopal. Poleg tega tvoja koda ne briše vejic ampak jih zamenjuje s presledki.
Kakorkoli:
string izbrisiVejice(string besedilo) { string nov = ""; for (int i = 0; i < besedilo.length(); i++) { if (besedilo[i] == ',') nov += ' '; //ce hoces odstranit, izpusti tole else nov += besedilo[i]; } return nov; }
Ps, če moraš na stringu samem naredit tole, potem funkcija z referenco in uporabljaš find ter replace.
Zgodovina sprememb…
- spremenil: darkkk ()
mallard ::
Kot ti je že darkkk povedal, v prazen niz ne moreš dostopat z operatorjem [] (no ja, lahko, ampak obnašanje programa je po C++ standardu v tem primeru nedefinirano; lahko bi se ti v niz napisalo Halo, kva pa delas?", kar se standarda tiče). Torej, znake moraš dodajat nizu, kot ti je darkkk pokazal, ali pa mu pred menjavanjem znakov nastavit velikost, v tvojem primeru enako kot originalnemu:
Razred string ima funkcijo push_back, s katero lahko dodajaš znake na konec niza. V tem primeru ti ni potrebno posebej povečevat niza, push_back to stori sam, ko je potrebno. Če veš, kako dolg bo nov niz, lahko prostor zanj vnaprej rezerviraš:
Še enovrstična rešitev z uporabo algoritma:
Kot že rečeno, s tem zamenjuješ vejice s presledki. če bi jih rad brisal, je pa najlažje takole:
Pa še to (v funkciji povprecjeZnakov):
To sta dva char-a, ne eden. Vklopi prevajalnikova opozorila na ful, tu bi ti moral zatežit, nekaj v smislu: "Warning multi-character character constant".
string nov; nov.resize(besedilo.length()); for ...
Razred string ima funkcijo push_back, s katero lahko dodajaš znake na konec niza. V tem primeru ti ni potrebno posebej povečevat niza, push_back to stori sam, ko je potrebno. Če veš, kako dolg bo nov niz, lahko prostor zanj vnaprej rezerviraš:
string izbrisiVejice(string besedilo) { string nov; nov.reserve(besedilo.length()); for (int i = 0; i < besedilo.length(); i++) nov.push_back(besedilo[i] == ',' ? ' ' : besedilo[i]); return nov; }
Še enovrstična rešitev z uporabo algoritma:
replace(besedilo.begin(), besedilo.end(), ',', ' ');
Kot že rečeno, s tem zamenjuješ vejice s presledki. če bi jih rad brisal, je pa najlažje takole:
besedilo.erase(remove(besedilo.begin(), besedilo.end(), ','), besedilo.end());
Pa še to (v funkciji povprecjeZnakov):
(besedilo[i] == '\r\n')
To sta dva char-a, ne eden. Vklopi prevajalnikova opozorila na ful, tu bi ti moral zatežit, nekaj v smislu: "Warning multi-character character constant".
Zgodovina sprememb…
- spremenilo: mallard ()
Klobasa ::
Sorry ne bi rad bil nekaj pameten, vendar si ne morem pomagat, da ne bi prilimal nekaj kar se nanaša tudi na to temo.
Use references for parameter passing and return value for types bigger than 4 bytes
Passing parameters by value results in the complete parameter being copied on to the stack. This is fine for regular types like integer, pointer etc. These types are generally restricted to four bytes. When passing bigger types, the cost of copying the object on the stack can be prohibitive. In case of classes there will be an additional overhead of invoking the constructor for the temporary copy that is created on the stack. When the function exits the destructor will also be invoked.
Thus it is efficient to pass references as parameters. This way you save on the overhead of a temporary object creation, copying and destruction. This optimization can be performed easily without a major impact to the code by replacing pass by value parameters by const references. (It is important to pass const references so that a bug in the called function does not change the actual value of the parameter.
Passing bigger objects as return values also has the same performance issues. A temporary return object is created in this case too.
Prefer int over char and short
With C and C++ prefer use of int over char and short. The main reason behind this is that C and C++ perform arithmetic operations and parameter passing at integer level, If you have an integer value that can fit in a byte, you should still consider using an int to hold the number. If you use a char, the compiler will first convert the values into integer, perform the operations and then convert back the result to char.
Use references for parameter passing and return value for types bigger than 4 bytes
Passing parameters by value results in the complete parameter being copied on to the stack. This is fine for regular types like integer, pointer etc. These types are generally restricted to four bytes. When passing bigger types, the cost of copying the object on the stack can be prohibitive. In case of classes there will be an additional overhead of invoking the constructor for the temporary copy that is created on the stack. When the function exits the destructor will also be invoked.
Thus it is efficient to pass references as parameters. This way you save on the overhead of a temporary object creation, copying and destruction. This optimization can be performed easily without a major impact to the code by replacing pass by value parameters by const references. (It is important to pass const references so that a bug in the called function does not change the actual value of the parameter.
Passing bigger objects as return values also has the same performance issues. A temporary return object is created in this case too.
Prefer int over char and short
With C and C++ prefer use of int over char and short. The main reason behind this is that C and C++ perform arithmetic operations and parameter passing at integer level, If you have an integer value that can fit in a byte, you should still consider using an int to hold the number. If you use a char, the compiler will first convert the values into integer, perform the operations and then convert back the result to char.
mm1992 ::
Tako nekako sem jaz naredil podobno.
Funkcija sprejme besedilo v obliki polja in izbriše vse nize ki se pojavijo v besedilu in so enaki nizu poslanemu preko paramatra "niz".
Upam da kaj pomaga
Funkcija sprejme besedilo v obliki polja in izbriše vse nize ki se pojavijo v besedilu in so enaki nizu poslanemu preko paramatra "niz".
string izbrisiVseZnake(string besedilo[], string niz) { string b = ""; for (int i = 0; i < VEL; i++) { string t = besedilo[i]; int x = 0; while ((x = t.find(niz)) != -1) { t = t.substr(0, x) + t.substr(x + niz.length(), t.length() - 1); } b += t + "\n"; } return b; }
Upam da kaj pomaga
Zgodovina sprememb…
- spremenil: mm1992 ()
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | c# programOddelek: Pomoč in nasveti | 1096 (921) | ZeleniJure |
» | Zakaj mi ne šteje presledkov ?Oddelek: Programiranje | 867 (723) | Ciklamen |
» | [C#] Domača naloga - osnoveOddelek: Programiranje | 2509 (1726) | 11tomi12 |
» | velike male besede c++Oddelek: Programiranje | 2584 (2200) | PoPon2 |
» | osnove v Javi - zvezdiceOddelek: Programiranje | 3575 (2797) | Tutankhamun |