Jak rozwinąć wyraz

0

Mam do napisania program, który z wyrazu A4BD powinien wydrukować AAAABD. Mam już warunek, ale nie wiem co wpisać w pętli while. A poza tym nic się nie wypisuje. Ktoś coś?

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main()
{
    string wyraz = "A4BD";
    int dlugoscWyrazu = wyraz.length();
    int liczba;
    char znak;

    for(int i = 0; i < dlugoscWyrazu; i++)
    {

        if(wyraz[i] == isdigit(wyraz[i]))
        {
            while(true)
            {
                cout << wyraz;
            }

        }
        else
        {
            //cout << wyraz[i];
        }
    }

    return 0;
}


1
if(wyraz[i] == isdigit(wyraz[i]))

sprawdzasz czy litera... jest równa prawdzie lub fałszowi - to nie ma sensu. Zastanów się co chcesz sprawdzać, opisz to własnymi słowami, a potem to zakodujemy.

0
kq napisał(a):
if(wyraz[i] == isdigit(wyraz[i]))

sprawdzasz czy litera... jest równa prawdzie lub fałszowi - to nie ma sensu. Zastanów się co chcesz sprawdzać, opisz to własnymi słowami, a potem to zakodujemy.

Chcę sprawdzić czy w stringu jest jakaś liczba. Jeśli jest to powinnam wypisać znak poprzedni tyle razy ile pokazuje cyfra

0

No to warunek to if(isdigit(wyraz[i]))

1
Magda Pietrzykowska napisał(a):

Chcę sprawdzić czy w stringu jest jakaś liczba. Jeśli jest to powinnam wypisać znak poprzedni tyle razy ile pokazuje cyfra

Która cyfra? Pierwsza cyfra w tej liczbie?

0

Zdaję sobię sprawę jakie jest zadanie, ale pytałem o tamtą konkretną linijkę. Shalom podał rozwiązanie, ale fajnie by było żebyś rozumiała dlaczego tak, a nie inaczej.

0
Burmistrz napisał(a):
Magda Pietrzykowska napisał(a):

Chcę sprawdzić czy w stringu jest jakaś liczba. Jeśli jest to powinnam wypisać znak poprzedni tyle razy ile pokazuje cyfra

Która cyfra? Pierwsza cyfra w tej liczbie?

Niekoniecznie pierwsza. Może też być coś takiego, np.A4BD3 i wtedy AAAABDDD

0
kq napisał(a):

Zdaję sobię sprawę jakie jest zadanie, ale pytałem o tamtą konkretną linijkę. Shalom podał rozwiązanie, ale fajnie by było żebyś rozumiała dlaczego tak, a nie inaczej.

Teraz już rozumiem. Dzięki wielkie

2
Magda Pietrzykowska napisał(a):
Burmistrz napisał(a):
Magda Pietrzykowska napisał(a):

Chcę sprawdzić czy w stringu jest jakaś liczba. Jeśli jest to powinnam wypisać znak poprzedni tyle razy ile pokazuje cyfra

Która cyfra? Pierwsza cyfra w tej liczbie?

Niekoniecznie pierwsza. Może też być coś takiego, np.A4BD3 i wtedy AAAABDDD

Nie o to mi chodziło. Może zakładasz, że wszystkie liczby będą jednocyfrowe i dlatego nazywasz całe te liczby cyframi, dlatego nie widzisz żadnego problemu. Jeśli tak, to nie było tematu.

0
Burmistrz napisał(a):
Magda Pietrzykowska napisał(a):
Burmistrz napisał(a):
Magda Pietrzykowska napisał(a):

Chcę sprawdzić czy w stringu jest jakaś liczba. Jeśli jest to powinnam wypisać znak poprzedni tyle razy ile pokazuje cyfra

Która cyfra? Pierwsza cyfra w tej liczbie?

Niekoniecznie pierwsza. Może też być coś takiego, np.A4BD3 i wtedy AAAABDDD

Nie o to mi chodziło. Może zakładasz, że wszystkie liczby będą jednocyfrowe i nazywasz te liczby cyframi, dlatego nie widzisz żadnego problemu. Jeśli tak, to nie było tematu.

A jaki byłby problem jeśli w wyrazie pojawiłyby się liczby?

3
Magda Pietrzykowska napisał(a):

A jaki byłby problem jeśli w wyrazie pojawiłyby się liczby?

Liczby jednocyfrowe to też liczby, ale domyślam się, że w tym pytaniu chodziło Ci o te wielocyfrowe. Pewnie problem byłby taki, że w Twojej wersji programu każda cyfra w wejściowym stringu będzie oznaczała, ile razy poprzedzający ją znak (niekoniecznie litera) pojawi się w wyjściowym stringu. Więc każda cyfra, która nie jest na pierwszej pozycji w liczbie, będzie oznaczała, ile razy poprzedzająca ją cyfra pojawi się w wyjściowym stringu.

Przykład:

Input: A23BC
Output: AA222BC
0
Burmistrz napisał(a):
Magda Pietrzykowska napisał(a):

A jaki byłby problem jeśli w wyrazie pojawiłyby się liczby?

Liczby jednocyfrowe to też liczby, ale domyślam się, że w tym pytaniu chodziło Ci o te wielocyfrowe. Pewnie problem byłby taki, że w Twojej wersji programu każda cyfra w wejściowym stringu będzie oznaczała, ile razy poprzedzający ją znak (niekoniecznie litera) pojawi się w wyjściowym stringu. Więc każda cyfra, która nie jest na pierwszej pozycji w liczbie, będzie oznaczała, ile razy poprzedzająca ją cyfra pojawi się w wyjściowym stringu.

Przykład:

Input: A23BC
Output: AA222BC

O tym nie pomyślałam. Wiesz może jak to ogarnąć?

0
Magda Pietrzykowska napisał(a):

O tym nie pomyślałam. Wiesz może jak to ogarnąć?

Moim zdaniem to powinno wynikać z treści zadania. Czy treść mówi o liczbach, cyfrach, jakoś to precyzuje?

0
Silv napisał(a):
Magda Pietrzykowska napisał(a):

O tym nie pomyślałam. Wiesz może jak to ogarnąć?

Moim zdaniem to powinno wynikać z treści zadania. Czy treść mówi o liczbach, cyfrach, jakoś to precyzuje?

Tylko jest napisane, aby wziąć to pod uwagę...

1

Pytanie brzmi czy musisz to pisać w ten sposób, czy np. możesz użyc http://www.cplusplus.com/reference/regex/ bo, wbrew temu co sie wydaje niektórym początkującym, biblioteki i mechanizmy języka są po to, zeby ułatwić pracę.

0
Shalom napisał(a):

Pytanie brzmi czy musisz to pisać w ten sposób, czy np. możesz użyc http://www.cplusplus.com/reference/regex/ bo, wbrew temu co sie wydaje niektórym początkującym, biblioteki i mechanizmy języka są po to, zeby ułatwić pracę.

Chcę to napisać jak najłatwiejszym sposobem, abym mogła zrozumieć, a zaznaczę, że jestem początkująca

Mam coś takiego, jednak nie wiem dlaczego nie wypisuje tyle znaków ile powinien

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main()
{
    string wyraz = "A4BD3";
    int dlugoscWyrazu = wyraz.length();
    int liczba;
    char znak;

    for(int i = 0; i < dlugoscWyrazu; i++)
    {

        if((isdigit(wyraz[i])))
        {
            while(wyraz[i]--)
            {

            }
            cout << wyraz[i-1];

        }

        else
        {
            cout << wyraz[i];
        }
    }

    return 0;
}
1

Chcę to napisać jak najłatwiejszym sposobem, abym mogła zrozumieć, a zaznaczę, że jestem początkująca

Tylko że właśnie najłatwiejszy sposób wymaga douczenia się takich rzeczy jak choćby te wspomniane regexy. Bo teraz to jest trochę tak jakbyś miała policzyć ile to będzie jak milion razy dodasz do siebie liczbę 2. My sugerujemy żeby przeczytała jak się mnoży, a ty próbujesz zrobić to najłatwiejszym sposobem, którym wg ciebie jest dodawanie po kolei...

Wbrew pozorom to co chcesz zrobić, korzystając tylko z podstawowych elementów składni, jest skomplikowane. Dużo bardziej niż ten kod który wstawiłaś, bo on zwyczajnie nie działa poprawnie.

0
Shalom napisał(a):

Chcę to napisać jak najłatwiejszym sposobem, abym mogła zrozumieć, a zaznaczę, że jestem początkująca

Tylko że właśnie najłatwiejszy sposób wymaga douczenia się takich rzeczy jak choćby te wspomniane regexy. Bo teraz to jest trochę tak jakbyś miała policzyć ile to będzie jak milion razy dodasz do siebie liczbę 2. My sugerujemy żeby przeczytała jak się mnoży, a ty próbujesz zrobić to najłatwiejszym sposobem, którym wg ciebie jest dodawanie po kolei...

Wbrew pozorom to co chcesz zrobić, korzystając tylko z podstawowych elementów składni, jest skomplikowane. Dużo bardziej niż ten kod który wstawiłaś, bo on zwyczajnie nie działa poprawnie.

Skoro tak to wygląda, to idę się douczać

0

Jeśli bardzo chcesz to robić ręcznie to musisz mieć drugą pętlę, która będzie skanować "całą liczbę" po napotkaniu cyfry. W ogóle nie dawałbym tu pętli for tylko while, bo będzie wygodniej, więc finalnie byłaby główna pętla while (zamiast twojego fora), a w środku while do pobrania całej liczby i kolejny while do wypisania zdekompresowanego ciagu znaków.

0
Magda Pietrzykowska napisał(a):

nie wiem dlaczego nie wypisuje tyle znaków ile powinien

Tak wygląda mój pomysł:

Dla każdego znaku:
    Jeżeli jest cyfrą:
        Pomnóż zapamiętaną liczbę przez 10 i dodaj aktualną cyfrę
    Jeżeli nie jest cyfrą:
        Jeżeli zapamiętana liczba ma wartość większą od 0:
            Wyświetl literę znajdującą się przed liczbą tyle razy, ile wynosi zapamiętana liczba minus 1
            Wyzeruj zapamiętaną liczbę
        Wyświetl aktualny znak    

Działa w C#, więc jeżeli zaimplementujesz to w C++, to też będzie działać. Nie musisz zapamiętywać litery znajdującej się przed liczbą, jeżeli będziesz pamiętała ilość cyfr w liczbie lub będziesz pamiętała liczbę jako string zamiast int. Dzięki temu uzyskasz indeks ostatnio odwiedzonej litery odejmując ilość cyfr i 1 od aktualnego indeksu.

0
import re
import string


def is_digit(val):
    return val in string.digits


def decompress1(data):
    result = ""
    current_letter = data[0]
    multiplier = 0
    for index in range(len(data)):
        if is_digit(data[index]):
            multiplier *= 10
            multiplier += ord(data[index]) - ord('0')
        elif multiplier > 0:
            result += current_letter * multiplier
            multiplier = 0
            current_letter = data[index]
        elif current_letter != data[index]:
            result += current_letter
            current_letter = data[index]
    if multiplier > 0:
        result += current_letter * multiplier
    else:
        result += current_letter
    return result


def decompress2(data):
    matches = re.findall("(\\w\\d*)", data)
    result = ""
    for match in matches:
        if len(match) > 1:
            result += match[0] * int(match[1:])
        else:
            result += match[0]
    return result


def main():
    data = "A10B20C"
    print(decompress1(data))
    print(decompress2(data))


main()
0

Coś takiego na szybkości:

#include <iostream>

void append_string_n_times(std::string &str, const int n)
{
    char appended_char = str.back();

    for (int i = 0; i < n - 1; i++)
        str += appended_char;
}

void decompress_string(const std::string src, std::string &out)
{
    for (int i = 0; i < src.length(); i++)
        if (isalpha(src[i]))
            out += src[i];
        else
            append_string_n_times(out, (int) src[i] - 48);
}

int main()
{
    std::string input = "A4B9D1";
    std::string output = "";

    decompress_string(input, output);

    std::cout << output;

    return 0;
}

Ale żeby to sensowniej funkcjonowało wypadałoby obsłużyć stringi typu A158BD, whitespacy i zastanowić się jaki chce się mieć output np. w takiej sytuacji: 5A0D 4C i odpowiednio rozwinąć program.

2

Trochę przekombinowujecie imo. Wystarczy użyć std::stoi (albo nawet atoi) jeśli pierwszym znakiem jest cyfra.

Niestety, obsługa RE w C++ nie jest trywialna, szczególnie dla początkujących, którzy z samymi regexami mogą mieć problemy.

0

Sam jestem początkujący. Moim zdaniem skoro ma wyjść z tego AAAABD to takie jest rozwiązanie i po co dalej kombinować i wymyślać czy to mają być kilku cyfrowe liczby czy tylko jednocyfrowe ;p Ja bym oddał taki kod jako rozwiązanie ale pewnie koledzy mają racje że lepiej chyba byłoby zrobić wersje dla kilku cyfrowych liczb.

#include <iostream>
#include <string>
#include <cctype>

using namespace std;

int main()
{
    string wyraz = "A4BD3";
    int dlugoscWyrazu = wyraz.length();
    int liczba;
    char znak;

    for (int i=0; i<wyraz.length(); i++) {
        znak = wyraz[i - 1];
        if (isdigit(wyraz[i])) {
            liczba = (int) wyraz[i] - 48; // https://stackoverflow.com/questions/5029840/convert-char-to-int-in-c-and-c
            for (int i=1; i<liczba; i++) {
                cout << znak;
            }
        } else {
            cout << wyraz[i];
        }
    }

    return 0;
}

g++ main.cpp -o out.exe

0

Tak, pisałem o tym w swoim poście, @Shalom. Tutaj wersja z liczbami większymi od 9:

#include <iostream>

void append_string_n_times(std::string &str, const int n)
{
    char appended_char = str.back();

    for (int i = 0; i < n - 1; i++)
        str += appended_char;
}

void decompress_string(const std::string src, std::string &out)
{
    for (int i = 0; i < src.length(); i++) {
        if (isalpha(src[i]))
            out += src[i];
        else {
            int n = (int) src[i] - 48;
            while (isdigit(src[i + 1])) {
                n *= 10;
                n += (int) src[i + 1] - 48;
                i++;
            }
            append_string_n_times(out, n);
        }
    }
}

int main()
{
    std::string input = "A10BDBDBDBDBD2257";
    std::string output = "";

    decompress_string(input, output);

    std::cout << output;

    return 0;
}

Patrzyłem wstępnie i działa, choć nie zdziwię się jeśli jednak coś nie działa. :D

1

topcoder material 4sure

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string wyraz = "ABCQ11ABC";
    string ilosc_powtorzen = "";
    string znak_do_powtorzenia = "";
    
    for(int i = 0; i < wyraz.length(); i++)
    {
        if(isdigit(wyraz[i]))
        {
            ilosc_powtorzen += wyraz[i];
            
            if (i == wyraz.length()-1 || !isdigit(wyraz[i+1]))
            {
                int ilosc = std::stoi(ilosc_powtorzen)-1;
                cout << std::string(ilosc, znak_do_powtorzenia[0] /* let's do not talk about this one */);
            }
        }
        else
        {
            znak_do_powtorzenia = wyraz[i];
            ilosc_powtorzen = "";
            cout << wyraz[i];
        }
    }

    return 0;
}
0

Chyba sprawa jest wyjaśniona, dzięki wszystkim za podpowiedzi

0

Jeśli chodzi o sam algorytm, być może logiczniej byłoby to zrobić na stosie na odwróconym stosie. Mówię jakby co.

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