Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wariancja bez powtórzeń

Ostatnio zmodyfikowano 2016-02-19 19:04
Autor Wiadomość
bleda
Temat założony przez niniejszego użytkownika
Wariancja bez powtórzeń
» 2016-02-13 12:18:35
Witam, chciałem zaiplementować wzór na wariancje bez powtórzeń - N!/(N-K)!*K!

Wzór kodu:
C/C++
main()
{
    wynik =(( silnia( n ) ) /( silnia( n - k ) ) *( silnia( k ) ) );
}



long int silnia( long int a )
{
    if( a > 1 )
    {
        return a *( silnia( a - 1 ) );
    }
}


Niestety podaje mi błędne wyniki :
Np dla:
N = 4 i K = 2 wynik = 24
N = 5 i K = 2 wynik = 40
Dla większych program się zawiesza.
P-144806
carlosmay
» 2016-02-13 15:21:36
C/C++
long int silnia( long int a )
{
    if( a > 1 )
    {
        return a *( silnia( a - 1 ) );
    }
}
Funkcja zwraca głupoty dla a < 2 (niezdefiniowane zachowanie).

wynik =(( silnia( n ) ) /( silnia( n - k ) ) *( silnia( k ) ) );
Nawiasów nastawiane, tylko nie tam gdzie trzeba.
Należy wziąć w nawias cały mianownik. W ten sposób zdeterminujesz odpowiednio obliczenia.

Dla większych program się zawiesza.
Niewłaściwy typ zmiennej (za mały rozmiar).
P-144817
Rashmistrz
» 2016-02-18 15:03:44
Mój puryzm językowy nakazuje mi zwrócić Ci uwagę,
że jest to "wariacja", a nie "wariancja".

1. n i k musi być większe od zera.
2. n musi być większe lub równe k.
3.
Niestety podaje mi błędne wyniki.
Źle zapisany wzór:
(( silnia( n ) ) /( silnia( n - k ) ) *( silnia( k ) ) );
.
Poprawnie powinno być:
silnia( n ) /( silnia( n - k ) * silnia( k ) );
.

4. Zgubiłeś
else
 (lub
return 1;
) po:
C/C++
if( a > 1 )
{
    return a *( silnia( a - 1 ) );
}


5.
Dla większych program się zawiesza.
a) Typ
unsigned long long int
 ma
   największy zakres liczb dodatnich całkowitych.
b) Już 13! przepełnia typ
long int
, pomyśl sobie,
   że jeszcze musisz mnożyć silnię przez silnię...
   (a później jeszcze podzielić silnię przez silnię)

Rozpisując silnię, otrzymamy iloczyny o dużej liczbie czynników.
Łatwo zauważyć, że część czynników będzie można zredukować,
czyli już na poziomie liczenia silni z n można pominąć część mnożeń.

Na przykład dla n=5 i k=3:
5! /  3! * (5-3)!
5! /  3! * 2!
(5*4*3*2*1) / ( (3*2*1) * (2*1) )
(5*4) / (2*1)
20 / 2
10

Implementacją powinieneś się już sam zająć.
P-144986
mateczek
» 2016-02-19 19:04:18
C/C++
#include <iostream>

using namespace std;

int main()
{
    // nie korzystaj z wzorów z matematyki bo przekombinowujesz !!!
    // w programie podaj najpierw większą cyfrę potem mniejszą  np 5 3.
    //wyjaśnienie poszczególnych działań:
    //kombinacje to -  k ostatnich cfr przez k pierwszych = (5*4*3)/(1*2*3) lub 5/1*4/2*3/3
    //wariancje bez powtórzeń to k ostatnich cyfr   5*4*3
    //wariancje z powtórzeniami to po prostu 5*5*5
   
    // strart program
    int k, n;
    int wariancjeBezPowt = 1;
    int kombinacje = 1;
    int wariancjeZPowt = 1;
    cin >> n >> k;
    for( int i = 1, j = n; i <= k; i++, j-- ) {
        kombinacje = kombinacje * j / i; //kombinacje jak byś chciał :P
        wariancjeBezPowt = wariancjeBezPowt * j; //wariancje bez powtórzeń !!!
        wariancjeZPowt = wariancjeZPowt * n; //wariacje z powtórzeniami jak byś chciał
    }
    cout << "kombinacja " << k << " z " << n << " = " << kombinacje << endl;
   
    cout << "wariancja bez powtorzen " << k << " z " << n << " = " << wariancjeBezPowt << endl;
   
    cout << "wariancja z powtorzeniam " << k << " z " << n << " = " << wariancjeZPowt << endl;
   
}
// jak chcesz optymalizacje w przypadku kombinacji to możesz skorzystać z właściwości C(4 z 5)=C(1 z 5)
//kombinacja cztery z pięciu daje taki sam wynik jak kombinacja jeden z pięciu.
//podobnie 3 z 5 to tak samo jak 2 z 5 a w drugim przypadku iteracji będą dwie !!!
P-145045
« 1 »
  Strona 1 z 1