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

petla for w rekurencji

Object Storage Arubacloud
0 głosów
888 wizyt
pytanie zadane 21 marca 2017 w C i C++ przez JamesBlant Początkujący (290 p.)

Witam, wie ktoś może jak skonstruaować funkcję rekurencyjną, która wypisywała, by znaki:

a,b,c,d...z, aa,ab,ac, ad..zz...aaa, aab...itd. Zrobiłem coś takiego, ale nie jestem zbyt z tego zadowolony: 

string funkcja(vector<char> napis){
    int x = napis.size()-1;
    for(int a='a';a<='z';a++){
    for(int b='a';b<='z';b++){
    for(int c='a';c<='z';c++){
    for(int d='a';d<='z';d++){
    for(int e='a';e<='z';e++){
    for(int f='a';f<='z';f++){
    for(int g='a';g<='z';g++){
    for(int h='a';h<='z';h++){
    for(int i='a';i<='z';i++){
    for(int j='a';j<='z';j++){
        napis[x-9] = a;
        napis[x-8] = b;
        napis[x-7] = c;
        napis[x-6] = d;
        napis[x-5] = e;
        napis[x-4] = f;
        napis[x-3] = g;
        napis[x-2] = h;
        napis[x-1] = i;
        napis[x-0] = j;
        cout <<
        napis[x-9] <<
        napis[x-8] <<
        napis[x-7] <<
        napis[x-6] <<
        napis[x-5] <<
        napis[x-4] <<
        napis[x-3] <<
        napis[x-2] <<
        napis[x-1] <<
        napis[x-0] <<
        endl;
    }}}}}}}}}}

wywołanie:
vector<char> napis(10,0);
funkcja(napis);

Niestety niedość, że od samego patrzenia na to bolą oczy to jescze funkcja zaczyna liczyć od 'aaaaaaaaaa', a nie od 'a'... Ma ktoś jakieś sugestie bądz, wskazówki?

4 odpowiedzi

0 głosów
odpowiedź 21 marca 2017 przez mokrowski Mędrzec (155,460 p.)

Pierwsza podpowiedz:

#include <stdio.h>
#include <stdlib.h>

void charGen(char c) {
    printf("%c,", c);
    if(c == 'z') {
        return;
    }
    charGen(c + 1);
}

int main(void) {
    charGen('a');

    return EXIT_SUCCESS;
}

 

komentarz 22 marca 2017 przez JamesBlant Początkujący (290 p.)
Po wielu próbach nadal nie wychodzi mi tak jak powinno :/
0 głosów
odpowiedź 22 marca 2017 przez JamesBlant Początkujący (290 p.)
Ma ktoś jeszcze jakieś sugestie?
0 głosów
odpowiedź 23 marca 2017 przez mokrowski Mędrzec (155,460 p.)

Jakoś nie widzę Twoich prób. Jeśli nie działa, pokaż co nie działa. 

Druga podpowiedź:

#include <stdio.h>
#include <stdlib.h>
 
void cGen(char c, size_t count) {
    if(!count) {
        return;
    }
    putchar(c);
    cGen(c, --count);
}
 
int main(void) {
    cGen('a', 7);

    return EXIT_SUCCESS;
}

 

komentarz 23 marca 2017 przez JamesBlant Początkujący (290 p.)
edycja 23 marca 2017 przez JamesBlant

Zrobiłem trochę inny, niby liczy dobrze, ale po jakimś czasie program się wywala.

Kod:

 

int i=0; << znienna globalna
string generator(string napis){
    napis[i]='a'-1;
    while(napis[i]<'z'){

         napis[i]++;
         cout << napis << endl;

         }
    int l=0;
    for(int j=0;j<i+1;j++)if(napis[j]=='z') l++;
    if(l==i+1){
        i++;
        for(int p=0;p<i+1;p++){
            napis[p]='a';
        }return generator(napis[i] + napis);
    }

    for(int x=0;x<i;x++){
        if(napis[i-x-1]!='z'&&napis[i-x]=='z'){
            napis[i-x-1]=napis[i-x-1]+1;
            napis[i-x]='a';
            return generator(napis);
        }
    }
}

int main(){
    string napis = "a";
    generator(napis);

}

Niestety, gdy licznik dojdzie do  okolic "uzry" dostaje komunikat - "program przestał działać". Gdy usune couta dzieje sie to samo...

komentarz 23 marca 2017 przez tangarr Mędrzec (154,780 p.)
Tak właśnie działa rekurencja w językach imperatywnych.
https://pl.wikipedia.org/wiki/Przepe%C5%82nienie_stosu
Rekurencja jest bardzo wredna. Unikaj jej jak ognia.
komentarz 23 marca 2017 przez mokrowski Mędrzec (155,460 p.)

A co ja bym radził? Ano to:

1. Nie "unikaj jak ognia" tylko zrozum i się naucz bo na językach imperatywnych świat się nie kończy (a nawet w takim C++ w szablonach jest wyłącznie rekurencja). Jeśli się jej nauczysz będziesz lepiej programował/programowała.

2. Miej świadomość konsekwencji stosowania oraz kruchości zabezpieczeń. Język C i C++ nie ma wpisanego w standardzie nawet wymagania implementacji rekurencji ogonowej. Z z praktyki jednak wiadomo (a taka podstawa wystarczy do ćwiczeń choć nie do pisania bardzo krytycznych aplikacji) że kompilatory GCC, CLANG oraz VS, stosują tę technikę już przy włączeniu najmniejszego stopnia optymalizacji.

3. Miej świadomość że są branże tworzenia oprogramowania gdzie techniki rekurencyjne w językach do tego nie dostosowanych są zabronione ze względu na ich bezpieczeństwo oraz możliwe konsekwencje awarii (np. systemy sterowania i branża systemów wbudowanych).

4. Miej świadomość że część języków (szczególnie funkcyjnych które stają się coraz bardziej popularne tak bezpośrednio jak i jako techniki tworzenia kodu) oparta jest o rekurencję i nie da się bez niej obejść.

A co do kodu @JamesaBlant'a...

  1. Co u Ciebie jest warunkiem stopu czyli kiedy program ma się skończyć? (potrzebna jest odpowiedź w stylu: "jak osiągnie wynik: abbd".
  2. Które zmienne zawierają stan wykonania programu? (czyli np. liczniki, długości, tablice wyników bieżących itp...). Stan ten powinieneś przekazać w wywołaniu rekurencyjnym aby kompilator mógł przeprowadzić optymalizację rekurencji ogonowej. Masz to w mojej 2 podpowiedzi. Popatrz na linię 9. Tam jest zmniejszenie i przekazanie licznika.

Być może zadanie jest jeszcze dla Ciebie zbyt trudne. Jeśli to nie zaliczenie lub inne tego typy "sytuacje podbramkowe", radzę zacząć od prostszych zagadnień rekurencyjnych.

0 głosów
odpowiedź 23 marca 2017 przez JamesBlant Początkujący (290 p.)
Teraz już wiem , jednak rekurencja w tym przypadku była strzałem w kolano. Jeżeli chodzi o C++ to dopiero się uczę i nie ogarniam jeszcze  z tego wszystkiego.

Ogólnie dzięki za pomoc, to była dla mnie dobra lekcja.

Podobne pytania

0 głosów
1 odpowiedź 177 wizyt
pytanie zadane 18 listopada 2016 w C i C++ przez Kunka Nowicjusz (170 p.)
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 2 listopada 2016 w JavaScript przez NaczelnyNieuk Początkujący (260 p.)
+1 głos
2 odpowiedzi 652 wizyt
pytanie zadane 27 lutego 2021 w JavaScript przez Darth Vader Początkujący (270 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...