Witam mam dziwny program jak wpisuje takie slowo "dddde" lub "dddfffggg" to mi się program wykrzacza. A powinienem mieć coś takiego "d3e" i "d2f2g2". I nie wiem czemu się tak dzieje.
#include <iostream>
#include <string>
#include <sstream>
int main()
{
int ile = 0;
std::cin >> ile;
for ( int i = 0 ; i < ile ; ++i)
{
std::string litera;
std::string koncowy_ciag;
koncowy_ciag.clear();
litera.clear();
std::cin >> litera;
int m = litera.size();
int flaga = 0;
for ( int k = 0 ; k < m ; ++k)
{
int pomicnicze_k = k;
int pom_k = k;
if ( litera[k] == litera[k+1])
{
++flaga;
if (flaga == 1)
{
koncowy_ciag += litera[pomicnicze_k];
koncowy_ciag += std::to_string( flaga );
}
else if ( flaga > 1 )
{
koncowy_ciag.erase(koncowy_ciag.begin()+pomicnicze_k);
koncowy_ciag += std::to_string(flaga);
}
}
else if ( (litera[k] != litera[k+1]) && ( flaga > 0 ) )
{
flaga = 0;
}
else if ( litera[k] != litera[k+1] )
{
koncowy_ciag += litera[pomicnicze_k];
}
k = pom_k;
}
std::cout << "to jest koncowy wyraz: " << koncowy_ciag << std::endl;
}
return 0;
}
I jak coś to program nie jest jeszcze skończony, ale nie mogę przez ten błąd ruszyć dalej.
EDIT: Dodano znacznik CODE
I oto wkraczam ja, z błyszczącym debuggerem w ręku...
1. Zaglądasz poza koniec łańcucha (operacje na litera[k+1]) - ale do "aktywacji" tego błędu nie docierasz...
2. Problemem jest linia z koncowy_ciag.erase(), pomicnicze_k robi się większe niż rozmiar koncowy_ciag i ustawiasz iterator "w kosmos" - dzieje się tak np. w 3 iteracji dla "dddde". koncowy_ciag ma wartość "d2", pomicnicze_k ma wartość 2 i iterator pokazuje za koniec stringa i erase się wykrzacza.
Algorytm lepiej zadziała dla "look behind" (pamiętaj poprzedni znak) niż "look ahead" (podglądaj następny znak).
#include <iostream>
#include <string>
#include <sstream>
int main()
{
std::string litera;
std::string koncowy_ciag;
int ile = 0;
std::cin >> ile;
for ( int i = 0; i < ile; ++i ) {
koncowy_ciag.clear();
litera.clear();
std::cin >> litera;
// Taki preset sprawi, że nie trzeba specjanie traktować pierwszego
// znaku
char poprzedni = litera[0];
int powt = 0;
// Prosta iteracja po kolejnych znakach std::string
for ( char zn : litera ) {
if ( zn == poprzedni ) {
// Jeżeli mamy jeszcze raz taki sam znak, to go zlicz
powt++;
} else {
// Jeżeli nie jest taki sam, to wyświetl poprzedni z odpowiednią
// liczbą powtórzeń, jeżeli trzeba
koncowy_ciag += poprzedni;
if ( powt > 1 ) koncowy_ciag += std::to_string( powt - 1 );
// I ustaw, że mamy 1 wystąpienie nowego znaku
powt = 1;
poprzedni = zn;
}
}
// Po ostatnim znaku do ciągu nie jest dodane ostatnie liczenie. Zrób
// to teraz.
koncowy_ciag += poprzedni;
if ( powt > 1 ) koncowy_ciag += std::to_string( powt - 1 );
std::cout << "to jest koncowy wyraz: " << koncowy_ciag << std::endl;
}
return 0;
}