Nowe posty

question rDNS i directadmin (0)
Dzisiaj o 15:59:15
xx Edycja pliku tekstoego (1)
Dzisiaj o 09:27:03
xx Teraz a kiedyś (3)
Wczoraj o 20:24:05
xx modem od dostawcy (1)
Wczoraj o 19:52:56
xx Postfix jako SMTP Proxy (1)
2019-02-13, 17:01:01
xx Zabezpieczenie przed nieautoryzowanym serwerem DHCP (2)
2019-02-13, 16:24:09
xx Programy antywirusowe - gdzie mają zastosowanie (6)
2019-02-10, 23:05:29
xx Kompilacja kernela. (6)
2019-02-07, 12:08:41
xx Od jakiego linuxa zacząć (1)
2019-02-06, 14:53:46
xx Wtyczki Photoshopa w GIMPie, pod Xubuntu. (1)
2019-02-05, 20:03:39

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

Offline MateuszA

  • Users
  • Użytkownik
  • **
  • Wiadomości: 70
    • Zobacz profil
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: 2464
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
    • Linuxpedia.PL
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
~Gentoo/FreeBSD/OpenBSD/Specjalizowane customy

Offline MateuszA

  • Users
  • Użytkownik
  • **
  • Wiadomości: 70
    • Zobacz profil
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.

Offline MateuszA

  • Users
  • Użytkownik
  • **
  • Wiadomości: 70
    • Zobacz profil
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: 2464
  • Lenistwo jest matką potrzeby = babcią wynalazku
    • Zobacz profil
    • Linuxpedia.PL
Odp: program źle zlicza litery
« Odpowiedź #4 dnia: 2016-11-01, 09:03:54 »
 ;)
Paweł Kraszewski
~Gentoo/FreeBSD/OpenBSD/Specjalizowane customy