Nowe posty

xx Dystrybucja pod HP Omen (6)
Wczoraj o 23:30:08
xx [Poradnik] Wyszukiwanie Sterowników (2)
Wczoraj o 21:08:23
lamp Problem z Linux Lite po instalacji (0)
Wczoraj o 19:50:30
xx Ile pingwinów? (1)
Wczoraj o 08:59:24
xx konfiguracja pale moon (0)
2024-03-24, 21:53:42
xx Plasma 6 w Neonie ssie trochę mniej ... (10)
2024-03-23, 02:38:11
xx problem z instalacja sterowników do karty sieciowej (3)
2024-03-18, 18:10:16
xx Plik abc.001 (1)
2024-03-17, 17:48:27
xx Zlecę dopracowanie programu w MatLab (0)
2024-03-13, 15:28:40
xx Linux Mint 21.3 XFCE brak dźwieku po paru minutach (karta muzyczna zintegrowana) (5)
2024-03-12, 23:07:01

Autor Wątek: program źle zlicza litery  (Przeczytany 3576 razy)

KelThuzad

  • Gość
program źle zlicza litery
« dnia: 2016-10-29, 18:57:14 »
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
« Ostatnia zmiana: 2016-10-29, 22:50:49 wysłana przez Paweł Kraszewski »

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: program źle zlicza litery
« Odpowiedź #1 dnia: 2016-10-29, 23:43:44 »
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;
}

Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

KelThuzad

  • Gość
Odp: program źle zlicza litery
« Odpowiedź #2 dnia: 2016-10-30, 12:31:52 »
Paweł a czy da radę jakoś poprawić tą cześć z erasem? Czy może lepiej zrobić to na tablicy charów? Wolałbym zrobić to sam.

KelThuzad

  • Gość
Odp: program źle zlicza litery
« Odpowiedź #3 dnia: 2016-10-31, 22:20:06 »
Udało mi się poprawić mój program Paweł. Dodałem index który się zlicza i jest nie zależny od index tego pierwszego fora( muszę teraz porobić testy jeszcze )

Offline Paweł Kraszewski

  • Administrator
  • Guru
  • *****
  • Wiadomości: 3049
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
Odp: program źle zlicza litery
« Odpowiedź #4 dnia: 2016-11-01, 09:03:54 »
 ;)
Paweł Kraszewski
~Arch/Void/Gentoo/FreeBSD/OpenBSD/Specjalizowane customy