• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Problem z zadaniem - JZLICZ - Zliczacz liter

Mały hosting, OGROMNE możliwości
0 głosów
825 wizyt
pytanie zadane 24 czerwca 2020 w C i C++ przez dernis Nowicjusz (120 p.)

Witam,

Jestem świeży w C++ i mam problem, bo nie wiem czy idę w dobrym kierunku.

Chce się pozbyć powtórzeń i wykorzystać do tego celu stringa:) i za pomocą jego znaków nie zaśmiecać zbędnie pamięci.

Wiem, że trochę wycięte to z zadania ale reszta to prostota jeśli chodzi o te powtórzenia testów i całe zdanie “getlinem” a interesuje mnie moje podejście i sam problem,  a nie cale zadanie:), bo może tracę czas, a wszyscy na forach tylko o tabelach, listach… grr… chcę coś swojego.

Chciałbym to zrobić najprościej. Moja koncepcja jest ukierunkowana w tym kierunku... stworzyć funkcję, która np sprawdzi mi obecny bufor przechowujący char z resztą znaków w ciągu, jeśli wystąpi to drugi raz to go nie wyświetli... Próbuje na różne sposoby ale nie potrafię tego mechanizmu zapisać...

Proszę o pomoc.

aktualny kod wygląda tak:

#include <iostream>
using namespace std;

int main()
{
string wyraz;
char buffor;

cout<<"Podaj wyraz: ";
cin>>wyraz;

int wynik=0;
int dlugosc=wyraz.length();

for(int i=0; i<dlugosc; i++)
{
    buffor=wyraz[i];

    wynik=0;

    for(int j=0; j<dlugosc; j++)
    {
        if(buffor==wyraz[j])
        {
            wynik++;
        }

    }
    cout<<buffor<<" - "<<"wystepuje: "<<wynik<<"razy"<<endl;
}

return 0;

 

1 odpowiedź

0 głosów
odpowiedź 24 czerwca 2020 przez j23 Mędrzec (195,220 p.)

Opcja z tablicą jest najoptymalniejszą, ale jak już musi być twój sposób, to:

int main()
{
    string wyraz;

    cout << "Podaj wyraz: ";
    cin >> wyraz;

    for (int i = 0; i < wyraz.length(); i++) {
        if (wyraz[i] == 0) continue;

        char ch = wyraz[i];

        int wynik = 0;

        for (int j = 0; j < wyraz.length(); j++) {
            if (ch == wyraz[j]) {
                wynik++;
                wyraz[j] = 0;
            }
        }

        cout << ch << " - " << "wystepuje: " << wynik << "razy\n";
    }

    return 0;
}

 

komentarz 24 czerwca 2020 przez dernis Nowicjusz (120 p.)

dzięki, hm..

for (int j = 0; j < wyraz.length(); j++) {
            if (ch == wyraz[j]) {
                wynik++;
                wyraz[j] = 0;
            }

w tej pętli liczy powtórzenia, a następnie podstawia za aktualnie sprawdzany znak 0?

a ten warunek 

if (wyraz[i] == 0) continue;

zwiększa iterację przeskakując do kolejnego elementu jeśli zobaczy na sprawdzanym indexie przypisane 0??

Nie używałem continue, więc musze ogranąć czy dobrze myślę:)

komentarz 24 czerwca 2020 przez VBService Ekspert (256,580 p.)

Dla "leniwców" szybka regułka. wink

... słowo kluczowe continue wykorzystuje się wtedy, gdy chcemy pominąć wykonywanie kodu znajdującego się w pętli - od miejsca wystąpienia słowa kluczowego continue,  aż do samego końca pętli. Mówiąc prościej: jeżeli w danym kroku pętli zostanie wywołane słowo kluczowe continue to krok aktualnie wykonywany zostanie zakończony, a następnie pętla przejdzie do wykonywania kolejnego kroku (iteracji). 

1
komentarz 24 czerwca 2020 przez j23 Mędrzec (195,220 p.)

@dernis,

a następnie podstawia za aktualnie sprawdzany znak 0

Nie znak 0, tylko wartość 0.

zwiększa iterację przeskakując do kolejnego elementu jeśli zobaczy na sprawdzanym indexie przypisane 0??

Z grubsza tak. Po co liczyć coś, co już zostało policzone?

komentarz 27 czerwca 2020 przez dernis Nowicjusz (120 p.)

Ok, dzięki za sugestie. 

 

Kod:

 #include <iostream>
using namespace std;

int main()
{
    string wyraz;
    char buffor;
    int t;

    cout<<"Podaj liczbe testow: ";
    cin>>t;
    cout<<"Podaj wyraz: ";
    getline (cin, wyraz);
    for(int k=0; k<t; k++)
    {
        getline(cin, wyraz);

        int wynik=0;
        int dlugosc=wyraz.length();

        for(int i=0; i<dlugosc; i++)
        {
            if((wyraz[i]==0)||(wyraz[i]==' ')) continue;
            buffor=wyraz[i];
            wynik=0;


            for(int j=0; j<dlugosc; j++)
            {
                if(buffor==wyraz[j])
                {
                    wynik++;
                    wyraz[j]=0;
                }
            }
            cout<<buffor<<" - "<<"wystepuje: "<<wynik<<" razy"<<endl;
        }
    }

    return 0;
}

 

i link: https://ideone.com/kTSyAr

Pytanie chyba już ostatnie.. Czy można to zrobić inaczej niż bez przechowania zliczonych elementów, żeby od razu po ilości testów  podać 2 zdania i zliczyć całość.

W sensie... żeby enter nie był rozpoznany jako koniec linii.. albo inaczej.. żebym mógł ilością testów wskazać ilość wierszy do pobrania, które są oddzielone enterem a dopiero później zliczyć całość??

komentarz 27 czerwca 2020 przez j23 Mędrzec (195,220 p.)

Chodzi Ci o to, żeby nie czytać liniami, tylko od razu całość? Jeśli tak, to czytaj znakami metodą std::istream::get. Choć nie widzę w tym sensu, zważywszy że zadanie masz podzielone na testy.

komentarz 27 czerwca 2020 przez dernis Nowicjusz (120 p.)
tak dokładnie, chce odczytać do zliczenia 2 linie na wejściu, bo każdy test zlicza znaki osobno dla zdania 1 i osobno dla zdania 2.

Chyba że jakoś źle interpretuje to zadanie..

Podobne pytania

0 głosów
1 odpowiedź 2,010 wizyt
pytanie zadane 29 lipca 2016 w C i C++ przez KiTroN Początkujący (300 p.)
0 głosów
2 odpowiedzi 1,111 wizyt
pytanie zadane 2 października 2018 w SPOJ przez krawiecki Początkujący (490 p.)
0 głosów
1 odpowiedź 493 wizyt
pytanie zadane 6 marca 2022 w Python przez ambitny Nowicjusz (120 p.)

93,719 zapytań

142,631 odpowiedzi

323,263 komentarzy

63,266 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...