Funkcja które rekurencyjnie oblicza iloczyn liczb podzielnych przez 3 lub przez 7 ciągu arytm.

0

Cześć!

Za zadanie mam napisać funkcję

int Iloczyn1(int a, int b, int c)

, która działa rekurencyjnie i oblicza iloczyn tylko liczb podzielnych przez 3 lub przez 7 z ciągu arytmetycznego, gdzie "a" jest wyrazem pierwszym, "b" różnicą tego ciągu z przedziału od a do c.

Jedyne co na obecną chwilę potrafię napisać to:

 
        static int Iloczyn1(int a, int b, int c)
        {
            if (c == a) return 0;
            // a tu kod na który nie mam pomysłu

        } 

Bardzo proszę o pomoc!
Pozdrawiam

1

Nawet ten krótki fragment napisałeś źle, jeśli a = c = 3, to iloczyn = 3 a nie 0.

0

No faktycznie... A w jaki sposób mogę to napisać dalej? Nie mam kompletnie pomysłu :/

1

Nie bardzo rozumiem zdanie. Zakładam, że ciąg (tzn. a i b są ustalone), a rekurencja ma dotyczyć zakresu c. Ponadto nie wiem jaka jest wartość iloczynu pustego zbioru liczb, przyjmuję, że 1.

int iloczyn(int a, int b, int c)
{
    if(c < a)
    {
        return 1;
    }
    if (c == a) 
    {   
        if(c % 3 == 0 || c % 7 == 0)
        {
            return a;
        }
        else
        {
            return 1;
        }
    }
    else
    {
        if((c - a) % b != 0)
        {
            return iloczyn(a, b, c-1);
        }
        else
        {
            if(c % 3 == 0 || c % 7 == 0)
            {
                return c*iloczyn(a,b,c-1);
            }
            else
            {
                return iloczyn(a,b,c-1);
            }
        } 
    }
}
0

Nie o to chodzi, jest to jeden ciąg, wyrazem pierwszym jest "a", ostatnim "c" a różnicą tego ciągu arytmetycznego jest "b".

 static int Iloczyn1(int a, int b, int c)
        {
            if (a > c) return 1;
            if (//warunek % 3 == 0 && //warunek % 7 == 0)
                return a * Iloczyn1(a + b, b, c);
            else return Iloczyn1(a+b, b, c);

        } 

Jak na razie mam pomysł na coś takiego ale nie wiem co mam wpisać aby if sprawdzał mi po kolei liczby czy są podzielne/niepodzielne itp.

1

Masz narzucone by iterować po zmiennej a? Takie iterowanie jest nienaturalne i bardzo skomplikuje kod, ja iterowałem po c.

0

Faktycznie... napisany przez Ciebie kod działa i się kompiluje, jednak nie wstawiałem go do kompilatora wcześniej, prześledziłem tylko wzrokiem i mi coś nie pasowało. Dopiero zaczynamy rekurencję i niestety średnio to rozumiem, wstawiam Twój kod z moją interpretacją (jest błędna) ale czy mógłbyś po kolei omówić co i jak/kiedy się kompiluje? Bardzo chciałbym poznać w jaki sposób działa ten kod.

 static int Iloczyn1(int a, int b, int c)
        {   //Wpisuję liczby a=1, b=1, c=5
            if (c < a)
            { //ten if odpada bo a nie jest większe niż c
                return 1;
            }
            if (c == a)
            { //pierwsza część tego if'a także odpada bo c nie jest równe a
                if (c % 3 == 0 || c % 7 == 0)
                {
                    return a;
                }
                else
                {
                    return 1;
                }
            }
            else
            { //druga część if'a się wykonuje (ta część wymaga większego omówienia)
                if ((c - a) % b != 0)
                { // c-a = 4 przy dzieleniu przez b=1 daje 1, czyli wynik jest różny od 0
                    return Iloczyn1(a, b, c - 1); //zwraca (1,1,4) ???
                }
                else //dalszej części nie umiem zinterpretować
                {
                    if (c % 3 == 0 || c % 7 == 0)
                    {
                        return c * Iloczyn1(a, b, c - 1);
                    }
                    else
                    {
                        return Iloczyn1(a, b, c - 1);
                    }
                }
            }
        } 

Nie wiem czy przykład z liczbami (1,1,5) jest odpowiedni jeżeli jakiś inny przedział bardziej obrazuje działanie programu to proszę je podać. Byłbym bardzo wdzięczny za tę pomoc! :)

1

Warunek (c - a) % b != 0 oznacza, że liczba c nie jest wyrazem ciągu arytmetycznego, zatem nie zmienia iloczynu. Pozostaje taki jak był dla c - 1.
Analogicznie jest gdy c nie dzieli się ani przez 3, ani przez 7. Jeśli c dzieli się przez jedną z tych liczb, to dotychczasowy iloczyn należy pomnożyć przez c.

0

Może trochę z innej beczki, napiszę moje wątpliwości, bo na prawdę, średnio to rozumiem...

 static int Iloczyn1(int a, int b, int c)
        {   
            if (c < a)
            { //to rozumiem, jeżeli c jest większe od a to zwraca 1
                return 1;
            }
            if (c == a)
            {  // to rozumiem częściowo, dlaczego gdy c przy dzieleniu przez 3 lub 7 ma zwrócić a? A dopiero w przeciwnym przypadku 1?
                if (c % 3 == 0 || c % 7 == 0)
                {
                    return a;
                }
                else
                {
                    return 1;
                }
            }
            else
            {  //skąd się wziął wzór/zapis że akurat ((c - a) % b != 0) to oznaca że c nie jest wyrazem ciągu arytmetycznego?
                if ((c - a) % b != 0)
                { 
                    return Iloczyn1(a, b, c - 1); //dlaczego zwraca akurat c-1, a nie c-2 czy c+b? skąd to jest?
                }
                else 
                {
                    if (c % 3 == 0 || c % 7 == 0) //czemu ten zapis się powtarza? był parę linijek wyżej, teraz znowu jest potrzebny?
                    {
                        return c * Iloczyn1(a, b, c - 1);
                    }
                    else
                    {
                        return Iloczyn1(a, b, c - 1);
                    }
                } //no i ogólnie nie widze w którym miejscu ten program sprawdza po kolei każdą liczbę czy spełnia te warunki, przy typowym przykładzie z silnią która pokazuje w jaki sposób działa rekurencja wszystko jest jasne, jakoś tutaj nie widzę tych odwzorowań
            }
        } 
1
  1. Gdy c=a, to mamy ciąg postaci 4 (pierwsza liczba nie dzieli się ani przez 3, ni przez 7) lub ciąg postaci 21 (pierwsza liczba dzieli się przez 3 lub przez 7). W drugim przypadku iloczyn wynosi oczywiście 21, w pierwszym nie ma żadnej liczby do mnożenia. Pisałem wcześniej, że przyjmuję iż iloczyn pustego zbioru liczb jest równy 1.
  2. Wiesz co to jest ciąg arytmetyczny? Przy oznaczeniach z zadania, jego wyrazy to a,a+b,a+2*b,..... Jest oczywiste, że jeśli liczba c jest wyrazem ciągu, to różnica c - a dzieli się przez b, a jak nie jest wyrazem ciągu to c-a nie dzieli się przez b.
  3. Poprzednio to sprawdzenie było przy założeniu, że c=a, teraz c!=a.
  4. Bo zwiększenie zakresu o jeden, które dopisuje liczbę spoza ciągu, nie zmienia iloczynu Iloczyn(a,b,c) = iloczyn(a,b,c-1).
  5. Nie rozumiem tej wątpliwości, kod (w funkcji silnia)
return n*silnia(n-1);

rozumiesz, a kodu (w funkcji iloczyn)return c*iloczyn(a,b,c-1);

 nie rozumiesz?
0
bogdans napisał(a):
  1. Gdy c=a, to mamy ciąg postaci 4 (pierwsza liczba nie dzieli się ani przez 3, ni przez 7) lub ciąg postaci 21 (pierwsza liczba dzieli się przez 3 lub przez 7). W drugim przypadku iloczyn wynosi oczywiście 21, w pierwszym nie ma żadnej liczby do mnożenia. Pisałem wcześniej, że przyjmuję iż iloczyn pustego zbioru liczb jest równy 1.
  2. Wiesz co to jest ciąg arytmetyczny? Przy oznaczeniach z zadania, jego wyrazy to a,a+b,a+2*b,..... Jest oczywiste, że jeśli liczba c jest wyrazem ciągu, to różnica c - a dzieli się przez b, a jak nie jest wyrazem ciągu to c-a nie dzieli się przez b.
  3. Poprzednio to sprawdzenie było przy założeniu, że c=a, teraz c!=a.
  4. Bo zwiększenie zakresu o jeden, które dopisuje liczbę spoza ciągu, nie zmienia iloczynu Iloczyn(a,b,c) = iloczyn(a,b,c-1).
  5. Nie rozumiem tej wątpliwości, kod (w funkcji silnia)
return n*silnia(n-1);

rozumiesz, a kodu (w funkcji iloczyn)return c*iloczyn(a,b,c-1);

 nie rozumiesz?


1. Prawie rozumiem gdy podam liczby (3,1,3), zwróci a czyli 3, gdy podam liczby (5,1,5) zwróci 1, a nie powinno 0? Przecież żadna liczba z danego ciągu nie spełnia warunku, 1 nie dzieli się ani przez 3 ani przez 7, więc nie powinno być 0? tak samo w pierwszym if'ie,  
```csharp
 if (c < a)
            { 
                return 1;
            }

<- tu nie powinno zwracać "0"?
2. Wiem co to jest ciąg arytmetyczny ale zawsze takie rzeczy zapisywałem jako wzory a nie jako rekurencja i mam problem aby się przestawić. Z tym warunkiem

 ((c - a) % b != 0) 

już rozumiem.
3. Rozumiem.
4. Nie rozumiem nadal. Gdy napisałem wszędzie

 Iloczyn1(a,b,c)

<- wyskakiwał błąd. Nadal nie mam pojęcia po co zmniejszamy o jeden. Co nam to daje? Rozumiem to, że kiedy daliśmy argumenty funkcji to ona tyle samo musi zwrócić tylko dlaczego w innej postaci? Wcześniej są zadeklarowane if'y i inne sposoby co program ma wypisać. Kod w funkcji silnia rozumiem, bo ma mnożyć wyraz o 1 mniejszy, gdybyśmy chcieli aby był to iloczyn co drugiej liczby to napisalibyśmy n-2. W takim razie mam to rozumieć, że zapis c-1 ma odejmować liczby po kolei i sprawdzać czy dla każdej liczby są spełnione warunki?

1
  1. Którego słowa w zdaniu

Pisałem wcześniej, że przyjmuję iż iloczyn pustego zbioru liczb jest równy 1
nie rozumiesz? Takie założenie ma uzasadnienie informatyczne, jeśli A jest kolekcją liczb (jest np. typu List<Double>) to iloczyn obliczamy tak:

Double result = 1.0;
for(Double number: A){
    result*=number;
}

Jeśli kolekcja jest pusta, to iloczyn wyjdzie 1.
4. iloczyn(a,b,c-1) to iloczyn liczb z przedziału [a,c-1] spełniających dodatkowy warunek (są podzielne przez 3 lub 7, należą do ciągu), iloczyn(a,b,c) to iloczyn liczb z przedziału [a,c] spełniających ten sam warunek. Czym się różnią te iloczyny:

  • czynnikiem c, jeśli c spełnia warunek, wtedy iloczyn(a,b,c) = c*iloczyn(a,b,c-1)
  • niczym, jeśli c nie spełnia warunku, wtdy iloczyn(a,b,c) = iloczyn(a,b,c-1).
0
bogdans napisał(a):
  1. Którego słowa w zdaniu

Pisałem wcześniej, że przyjmuję iż iloczyn pustego zbioru liczb jest równy 1
nie rozumiesz? Takie założenie ma uzasadnienie informatyczne, jeśli A jest kolekcją liczb (jest np. typu List<Double>) to iloczyn obliczamy tak:

Double result = 1.0;
for(Double number: A){
    result*=number;
}

Jeśli kolekcja jest pusta, to iloczyn wyjdzie 1.

  1. iloczyn(a,b,c-1) to iloczyn liczb z przedziału [a,c-1] spełniających dodatkowy warunek (są podzielne przez 3 lub 7, należą do ciągu), iloczyn(a,b,c) to iloczyn liczb z przedziału [a,c] spełniających ten sam warunek. Czym się różnią te iloczyny:
  • czynnikiem c, jeśli c spełnia warunek, wtedy iloczyn(a,b,c) = c*iloczyn(a,b,c-1)
  • niczym, jeśli c nie spełnia warunku, wtdy iloczyn(a,b,c) = iloczyn(a,b,c-1).
  1. No wydaje mi się że nadal nie rozumiem, gdy dam liczby a=1, b=4, c=1 to żadna z tych liczb nie spełnia warunku podzielności przez 3 i przez 7, bo przedział danych liczb wynosi 1, a gdyby rozpisać, to powinien być zbiór pusty, a skoro żadna liczba nie należy to "0", gdy dam liczby a=8, b=10, c=8, też wychodzi 1 a przecież żadna liczba nie należy...

Poza tym, chyba w kodzie jest błąd bo gdy za a=0 a potem liczby dowolne to i tak wyjdzie 0, a przecież dla a=0, b=1, c=6, czyli z przedziału (0,6) są dwie liczby które spełniają 3 i 6, czyli iloczyn 18.

Dalej chyba wszystko jest jasne :)

1

Uparłeś się, że dla zbioru pustego iloczyn ma być 0. Ja przyjąłem, że 1 i podałem argument za. Najlepiej spytaj prowadzącego.

Poza tym, chyba w kodzie jest błąd bo gdy za a=0 a potem liczby dowolne to i tak wyjdzie 0, a przecież dla a=0, b=1, c=6, czyli z przedziału (0,6) są dwie liczby które spełniają 3 i 6, czyli iloczyn 18.
Nieprawda, są trzy liczby 0, 3 i 6.

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