Rekurencja w funkcji

0
#include<iostream>
using namespace std;
int liczba, wynik = 1;
 
int obliczanie(int wynik)
{
 
 
    if (liczba == 0)
        return 1;
    else return wynik * obliczanie(wynik-1);
   
}
 
 
int main(){
    cout << "Podaj liczbe: ";
    cin >> liczba;
    cout << liczba << "! = ";
    cout << obliczanie(wynik);
 
    return 0;
}

kompiluje ale potem wywala błąd, ktoś cos?

0

Masz tam 2 zmienne: liczba i wynik i używasz ich tak jakby to było to samo. Sprawdzasz jedno, drugie przekazujesz.

0

czyli w 5 linijce kodu powinno być int obliczanie(int liczba) ?

0

Tak, wszędzie ma być jedna zmienna, albo liczba, albo wynik, czyli najlepiej zamienić if (liczba == 0) na if (wynik == 0). Poza tym uważam, że rekurencyjna silnia to rak.

2

Może inaczej - co planujesz obliczyć? Bo ten kod średnio ma sens

1

Powinno być z głową.
Jak masz funkcje, przekazujesz wynik, wołasz funkcję z wynik to sprawdzaj też czy wynik jest równy zero. Jak w main wczytujesz liczba i pewnie chcesz liczyć dla liczba to przekazuj do funkcji liczba.

0

Napisz funkcję, która wyznacza wartość n! (n jest liczba naturalną). Funkcja ma
wykorzystywać rekurencję.
to jest treść zadania.
czyli jak dobrze zrozumiałem błędem w tym zadaniu były zmienne w funkcji w tym miejscu > int obliczanie(int wynik)
{

if (liczba == 0)
    return 1;
else return wynik * obliczanie(wynik-1);

}

i zamiast if (liczba ==0) powinno być if(wynik==0) tak? czy źle zrozumiałem

0

nie smiga :(

1

Jakbyś linię int liczba, wynik = 1; miał w main a nie globalnie to miałbyś błąd kompilacji i pewnie szybciej byś zauważył że napisałeś nie to co chcesz. Ogólnie zmienne globalne to zło i najlepiej ich nie używać

3

wywal te zmienne globalen i Używaj tego normalnie:

int badFactorial(int n) {
	if (n == 0) return 1;
	else return n * badFactorial(n - 1);
}
int main(){
	int num;
	std::cin >> num;
	std::cout<< badFactorial(num);
	std::cout << "\n";
	return 0;
}
1

Zacznijmy od tego, że tutaj masz odpowiedź:

http://cpp0x.pl/kursy/Kurs-C++/Poziom-5/Rekurencja/585

Drugie. Panie w czopce pirata @Kamil Żabiński "Ogólnie zmienne globalne to zło i najlepiej ich nie używać"

Czyli sugerujesz Nam, że np. serwer do gry MMORPG, powinien co jakieś 3ms ściągać dane gracza z bazy danych i w ogóle nie korzystać z globalnych zmiennych?

Tak samo, jeśli np. mamy jakąś firmową aplikację, zajmującą się obsługą klientów.. to każda jedna pojedyncza dana, powinna być ściągana co pare sekund, tylko po to, żeby pozbyć się globalnych zmiennych? Ja już nie mam wątpliwości, że ten kraj jest obsranym guwnem z wiedzą takich "dorosłych piratów", którzy budują nasz wizerunek na arenie międzynarodowej. Nie pozdrawiam.

P.S.: https://pl.linkedin.com/in/kamil-%C5%BCabi%C5%84ski chciałbym tylko spojrzeć na kawałek tego kodu wydanego z pod Pańskich łapek. I w chwili zadumy i milczenia usunąć się w cień.

1

Kilka przykładów różnych implementacji silni.

int factorialRecursive( int n )
{
	return (n<2)?1:n*factorialRecursive(n-1);
}

int factorialTail( int n , int ret=1 )
{
	return (n<2)?ret:factorialTail(n-1,ret*n);
}

int factorialProcedural( int n )
{
	int ret {1};
	for( auto i=1 ; i<=n ; ++i) ret *= i;
	return ret;
}

int factorialCacheProcedural( int n )
{
    if( n<0 ) return 1;
	static vector<int> cache {1};
	if( n>=cache.size() )
	{
	    cache.resize(n+1);
	    for( int i=cache.size()-1 ; i<=n ; ++i ) cache[i]=i*cache[i-1];
	}
	return cache[n];
}

int factorialCacheRecursive( int n )
{
    if( n<0 ) return 1;
	static vector<int> cache {1};
	if( n>=cache.size() )
	{
	    cache.resize(n+1);
	    if( n>0 ) cache[n] = n*( (n-1<cache.size())?cache[n-1]:factorialCacheRecursive(n-1) );
	}
	return cache[n];
}
0

Ja to bym tak zrobił

std::optional<int> factorial(int n)
{
    static constexpr int ret[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600};
    return n >= 0 && n < std::size(ret) ? std::optional{ret[n]} : std::nullopt;
}
0

znalazłem błąd istniał on w deklaracji funkcji oraz jej wywołaniu.
Pozostawiam sprawdzony i skompilowany kod dla potomnych niżej

#include<iostream>
using namespace std;
int liczba, wynik;
 
int obliczanie(int l)
{
 
    if (l == 0)
        return (1);
    else
    return l* obliczanie(l - 1);
 
}
 
int main() {
    cout << "Podaj liczbe: ";
    cin >> liczba;
    cout << liczba << "! = ";
 cout << obliczanie(liczba);
 
    return 0;
}
0
MexikanoS napisał(a):

Zacznijmy od tego, że tutaj masz odpowiedź:

http://cpp0x.pl/kursy/Kurs-C++/Poziom-5/Rekurencja/585

Drugie. Panie w czopce pirata @Kamil Żabiński "Ogólnie zmienne globalne to zło i najlepiej ich nie używać"

Czyli sugerujesz Nam, że np. serwer do gry MMORPG, powinien co jakieś 3ms ściągać dane gracza z bazy danych i w ogóle nie korzystać z globalnych zmiennych?

Tak samo, jeśli np. mamy jakąś firmową aplikację, zajmującą się obsługą klientów.. to każda jedna pojedyncza dana, powinna być ściągana co pare sekund, tylko po to, żeby pozbyć się globalnych zmiennych? Ja już nie mam wątpliwości, że ten kraj jest obsranym guwnem z wiedzą takich "dorosłych piratów", którzy budują nasz wizerunek na arenie międzynarodowej. Nie pozdrawiam.

P.S.: https://pl.linkedin.com/in/kamil-%C5%BCabi%C5%84ski chciałbym tylko spojrzeć na kawałek tego kodu wydanego z pod Pańskich łapek. I w chwili zadumy i milczenia usunąć się w cień.

Tak tutaj jeszcze nie zostałem nigdy zwyzywany.

Oczywiście, że cache różnego rodzaju jest potrzebne, nie zaprzeczam temu. Wielokrotnie także sam używałem czy to cache wewnętrze (np z Guavy) czy zewnętrzne jak Redis czy kombinowane jak Hollow.

Zauważ Pan jednak, że tutaj swoją radę kieruje do początkującego programisty, który ma problemy z najprostszym algorytmem rekurencyjnym. Zanim zacznie pisać aplikacje serwerowe minie pewnie jeszcze z rok (no chyba że naprawdę szybko się uczy). Przez ten rok zauważy pewnie, że do każdej "złotej zasady" w informatyce istnieje lista wyjątków. Niestety informatyka nie jest nauką totalnie ścisłą jak matematyka, że można udowodnić ,że jest tak, a nie inaczej. Zawsze operujemy na jakichś przybliżeniach i wzajemnie wykluczających się radach.

Serdecznie pozdrawiam

PS. Polecam medytację, żeby Pana nigdy więcej nie ponosiło.

PS2. Na co dzień najwięcej programuję w Javie (widać to dobrze na moim linkedinie). W Javie nie ma zmiennych globalnych. A nawet jeśli by się uprzeć że statyczne są globalne to odradza się ich używanie. Zamiast tego tworzy się pojedynczy obiekt, który przekazuje się wszędzie, gdzie jest potrzebny. Dzięki temu można łatwiej testować taki kod i za pomocą konfiguracji wybierać którą wersję globalnego obiektu wolimy używać

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