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;
}