[c++]Spacje - łatwe na stringi

0

Witam!
Mam problem z zadniem ze spoja - spacje.
Link:
http://pl.spoj.pl/problems/JSPACE/

Program nie chce działać, gdy pomiędzy wyrazami ma więcej spacji. Dla wyrażenia z jedną spacją działa: "Ala ma kota " zamienia na "AlaMaKota" itp.
Jednak już "Ala ma kota" zamienia na "Ala maKota". Nie wiem z czego to się bierze, mój program wygląda tak:

#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    string napis;
    while(getline(cin , napis))
    {
        int dl = napis.size();
        for(int i=0; i<dl; i++)
        {
            if(isspace(napis[i])) // sprawdzam czy aktualny znak w stringu jest spacją
            {
                if (isalpha(napis[i+1])) // jeśli tak, to sprawdzam czy kolejny jest literą
                {
                    napis[i] = napis[i+1] - 32; //wtedy ją zamieniam na dużą i cofam o jeden do tyłu
                    for(int a=1; a<dl-i; a++)
                        napis[a+i] = napis[i+a+1]; // cofam cały wyraz o jeden (bo przecież usunąłem spację)
                }
                else if (isspace(napis[i+1])) // jeśli kolejny znak jest też spacją
                {
                    for(int a=0; a<dl-i; a++)
                        napis[a+i] = napis[i+a+1]; // to przesuwam cały ciąg o jeden i w ten sposób usuwam tę spację
                }

            }

        }
        cout << napis << endl; //wypisanie zmodyfikowanego napisu
    }
}
 

W komentarzach opisałem pokrótce jak chciałem zrealizować 'algorytm' do tego zadania. Nie wyszło dla 'multispacji'.

Z góry dzięki za jakieś wskazówki, ja siedzę nad tym już z godzinę i się poddałem ;s

0

A może zamiast sobie przesuwać po tablicy (co generuje problemy) przepisuj do nowej...? Dwa oddzielne iteratory, nie kolidujące ze sobą... powinno być łatwiej.

Albo - zamiast

else if (isspace(napis[i+1])) // jeśli kolejny znak jest też spacją
                {
                    for(int a=0; a<dl-i; a++)
                        napis[a+i] = napis[i+a+1]; // to przesuwam cały ciąg o jeden i w ten sposób usuwam tę spację
                }

zrób po prostu i--;

0

Też uważam że lepiej przepisać do nowej tablicy. A tak w ogóle, to czemu nie std::string? Wystarczy string::erase i string::replace

0

Zrobiłem to tak:

#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    string napis, wynik;
    while(getline(cin , napis))
    {
        wynik = napis;
        int dl = napis.size();
        for(int i=0; i<dl; i++)
        {
            if(isspace(napis[i]))
            {
                if (isalpha(napis[i+1]))
                {
                    wynik[i] = napis[i+1] - 32;
                    for(int a=1; a<dl-i; a++)
                       wynik[a+i] = napis[i+a+1];
                }
                else if (isspace(napis[i+1]))
                {
                    for(int a=0; a<dl-i; a++)
                        wynik[a+i] = napis[i+a+1];
                }

            }
            else
                wynik[i] = napis[i];

        }
        cout << wynik << endl;
    }
}

 

To podwaja mi wypisywane literki, źle działa nawet w przypadkach, kiedy wcześniej działał dobrze...
A jeśli nie daję tego 'wynik = napis' to program wypisuje pustą linijkę

help!

To mi wypisuje w każdym przypadku tylko pustą linijkę ;s

0

CO według ciebie robi linijka: wynik = napis; ?!
Zastanów się jeszcze raz nad zadaniem. Dwie tablice. Dwa iteratory. Przepisujesz tylko znaki, które nie są spacjami. Możesz ustawiać sobie zmienną, która będzie ci mówić, czy powiększyć literę czy nie. Pętla idzie po tablicy wejściowej, iterator tablicy wyjściowej zwiększasz tylko gdy coś przepiszesz. To powyżej to jakaś bzdura. Po co stosujesz dwie tablice jak nie zmieniłeś logiki programu? Wywoływanie drugiego fora, bo dalej może być spacja jest błędne w założeniu - co jak będą 3, albo 4 spacje?

0

Zmieniłem wg w/w wskazówek. Kod wygląda tak:

#include <iostream>
#include <cctype>

using namespace std;

int main()
{
    string napis, wynik;
    bool czy = false;
    while(getline(cin , napis))
    {
        int dl = napis.size();
        for(int i=0; i<dl; i++)
        {
            if(!isspace(napis[i]))
            {
                if(!czy)
                    wynik[i] = napis[i];
                else
                {
                    wynik[i] = toupper(napis[i]);
                    czy = false;
                }
            }
            else
                czy = true;
        }
        cout << wynik << endl;
    }
}
 

Program dla każdego wejścia wypisuje pustą linijke. Co się dzieje ?

0

Zrób DWA ITERATORY, oddzielny dla tablicy wejściowej i wyjściowej!!

0
 #include <iostream>
#include <cctype>

using namespace std;

int main()
{
    string napis, wynik;
    bool czy = false;
    while(getline(cin , napis))
    {
        int dl = napis.size();
        for(int i=0, j=0; i<dl; i++)
        {
            if(!isspace(napis[i]))
            {
                if(!czy)
                {
                    wynik[j] = napis[i];
                    j++;
                }

                else
                {
                    wynik[j] = toupper(napis[i]);
                    j++;
                    czy = false;
                }
            }
            else
                czy = true;
        }
        cout << wynik << endl;
    }
}

Błąd jak wyżej.

0

Ok, odpaliłam ten twój kod - i wiesz że masz tam wyjątek "subscript out of range"? Albo inicjuj stringa, albo rób to na tablicach charów. Wynik jest nie inicjowany.

1 użytkowników online, w tym zalogowanych: 0, gości: 1