[C++] Sprawdzanie czy wśród liczb są naturalne

matemix
Użytkownik
Użytkownik
Posty: 465
Rejestracja: 10 cze 2008, o 19:38
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 12 razy
Pomógł: 1 raz

[C++] Sprawdzanie czy wśród liczb są naturalne

Post autor: matemix »

Potrzebuję wprowadzić kilka modyfikacji do gotowego programu sprawdzającego, czy wśród wszystkich kombinacji liczb:

\(\displaystyle{ w = \frac {2^{x_{1}} + 2^{x_{2}} \cdot \frac {p}{2} + 2^{x_{3}} \cdot \frac {p^{2}}{2^{2}} + ... + 2^{x_{n}} \cdot \frac {p^{y-1}}{2^{y-1}}}{2^{y+x}-p^{y}}}\)

występują liczby naturalne. Przy czym \(\displaystyle{ x_{1},...,x_{n} \in [0,x]}\) oraz \(\displaystyle{ x_{1} \ge, x_{2} \ge ... \ge x_{n}}\)

1. Chcę, by po zakończeniu pracy program ponownie poprosił o zmienne. Wiem, że nad wszystkim trzeba ustawić pętlę. Nie wiem jaką dokładnie.

2. Chcę, aby program co 3 minuty wypisywał informację o postępach procentowo z dokładnością do powiedzmy 3 miejsc po przecinku. Najlepiej chyba zrobić to licząc raz liczbę wszystkich kombinacji, daną wzorem:

\(\displaystyle{ \frac {y} {x+y} \cdot {x+y \choose y}}\)

i porównując ją z liczbą dotychczas policzonych kombinacji (program sukcesywnie tworzy kolejne liczby zadane wzorem, aż wyczerpie wszystkie możliwe kombinacje). Przy czym podobno z liczeniem symbolu newtona w C++ da dużych wartości (lub z liczeniem silni) jest jakiś problem, więc może lepiej zastosować do tego wzór Stirlinga.

3. Czy test naturalności nie wymaga poprawy? Sądzicie, że będzie dobrze działał? Znacie jakiś lepszy test?

Czy ktoś powie mi jak to zrobić? Poniżej podaję kod programu, nie ja go napisałem.

Kod: Zaznacz cały

#include <iostream>
#include <iomanip>
using namespace std;
#include <conio.h>
#include <string>
#include <vector>
#include <cmath>
#include <limits>

//====================================================================================================================

double computeW( int pX, int pY, int pP, const vector < vector < int >>& pXn, const vector < int >& pXIndxs );
bool isNaturalNum( double value );
double newton( unsigned int n, unsigned int k );

//====================================================================================================================

int main()
{
    int p;
    int y;
    int x;
    
    cout << "Podaj p: ";
    cin >> p;
    cout << "Podaj y: ";
    cin >> y;
    cout << "Podaj x: ";
    cin >> x;
    
    vector < vector < int >> xn( y - 1, vector < int >( x + 1 ) );
    
    for( auto & vec: xn )
    {
        for( int i = 0; i <= x; ++i )
        {
            vec[ i ] = i;
        }
    }
    
    vector < int > xIndxs( xn.size(), 0 );
    double w;
    bool exit = false;
    double counter = 0;
    unsigned long long howManyFound = 0;
    
    cout << "Start " << endl;
    
    while( !exit )
    {
        counter++;
        
        w = computeW( x, y, p, xn, xIndxs );
        if( isNaturalNum( w ) )
        {
            ++howManyFound;
            
            cout << "w= " << fixed << w << "; ";
            for( int i = 0; i < xn.size(); ++i )
            {
                cout << "x" << i + 1 << "=" << xn[ i ][ xIndxs[ i ] ] <<( i == xn.size() - 1 ? ""
                    : ", " );
            }
            cout << endl;
        }
        
        ++xIndxs[ 0 ];
        
        for( int j = xIndxs.size() - 1; j > 0; --j )
        {
            if( xIndxs[ j ] == x )
            {
                if( j == xIndxs.size() - 1 ) { exit = true; break; }
                
                ++xIndxs[ j + 1 ];
                
                for( int pom = j; pom >= 0; --pom )
                {
                    xIndxs[ pom ] = xIndxs[ j + 1 ];
                }
                
                break;
            }
        }
        
        if( xIndxs[ 0 ] == x + 1 )
        {
            if( xIndxs.size() >= 2 )
            {
                ++xIndxs[ 1 ];
                xIndxs[ 0 ] = xIndxs[ 1 ];
            }
            else
            {
                exit = true;
            }
        }
    }
    
    cout << "Koniec" << endl;
    cout << "wszystkich iteracji: " << fixed << setprecision( 0 ) << counter << endl;
    cout << "Policzonych, calkowitych liczb w: " << howManyFound << endl;
    
    getch();
    return 0;
}
//====================================================================================================================
double computeW( int pX, int pY, int pP, const vector < vector < int >>& pXn, const vector < int >& pXIndxs )
{
    double retVal = 0;
    
    int lastPow;
    for( int i = 0; i < pXn.size(); ++i )
    {
        retVal += pow( 2, pXn[ i ][ pXIndxs[ i ] ] ) * pow( pP, i ) / pow( 2, i );
        
        lastPow = i + 1;
    }
    
    retVal += pow( pP, pY - 1 ) / pow( 2, pY - 1 );
    retVal *= pow( 2, pY - 1 );
    retVal /= pow( 2, pX + pY ) - pow( pP, pY );
    
    return retVal;
}

//*****************************************************************************
bool isNaturalNum( double value )
{
    unsigned long long intPart = value;
    double rest = value - intPart;
    
    return rest == 0;
}
//*****************************************************************************
double newton( unsigned int n, unsigned int k ) // not working
{
    double Wynik = 1;
    
    for( unsigned int i = 1; i <= k; i++ )
    {
        Wynik = Wynik *( n - i + 1 ) / i; // Obliczanie ze wzoru iteracyjnego
    }
    
    return Wynik;
}
Ostatnio zmieniony 26 mar 2016, o 08:05 przez Afish, łącznie zmieniany 2 razy.
Powód: Poprawa wiadomości. Staraj się lepiej dobierać nazwy tematów, tak by wskazywały o czym jest treść zadania.
miodzio1988

[C++] Sprawdzanie czy wśród liczb są naturalne

Post autor: miodzio1988 »

a kto te kody pisał?

No sorry ale jak widać tekst:

Kod: Zaznacz cały

 // not working
To po co to wrzucasz? Żeby pokazać, że sam nic nie zrobiłeś i szukasz z miejsca gotowców?
matemix
Użytkownik
Użytkownik
Posty: 465
Rejestracja: 10 cze 2008, o 19:38
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 12 razy
Pomógł: 1 raz

[C++] Sprawdzanie czy wśród liczb są naturalne

Post autor: matemix »

miodzio1988 pisze:a kto te kody pisał?
Osoba, którą poprosiłem o pomoc w napisaniu tego programu i, który okazał się na tyle skomplikowany dla mnie, że nie do końca rozumiem co się w nim dzieje. Choć z początku sądziłem, że sam będę w stanie go napisać.
miodzio1988 pisze: No sorry ale jak widać tekst:

Kod: Zaznacz cały

 // not working
To po co to wrzucasz? Żeby pokazać, że sam nic nie zrobiłeś i szukasz z miejsca gotowców?
Szukam gotowców lub sugestii. Znam zupełne podstawy programowania w C, z C++ dopiero się zaznajamiam. Nie napisałem tego programu i rozumiem jego działanie wybiórczo. Jednak wiem, że modyfikacje jakie potrzebuję wprowadzić są kosmetyczne, stąd z tym pewnie poradzę sobie sam.

Nie wiem co robi część oznaczona not working, ale chyba miała liczyć wartość symbolu newtona i można ją równie dobrze usunąć z programu, w każdym razie cytowany kod jest niezmieniony. A próby zmiany, które podejmowałem kończyły się błędami już na poziomie kompilacji. Poza jedną zmianą, którą udało mi się wprowadzić - sprawdzanie przypadków, gdy dzielnik \(\displaystyle{ 2^{x+y}-p^{y}}\) będzie ujemny - wziąłem po prostu wartość bezwzględną:

Kod: Zaznacz cały

retVal /= abs(pow( 2, pX + pY ) - pow( pP, pY ));
I program w tym momencie sprawdza całkowitość liczby \(\displaystyle{ w}\), a nie tylko naturalność. Ponadto informuje, że wyniki to liczby ujemne, bo dodałem:

Kod: Zaznacz cały

 if(pow( 2, y+x )-pow( p, y )<0)
{
    cout << "Ujemne" << endl;
}
Wprowadzenie pozostałych zmian na razie mi nie wychodzi lub nie wiem jak je zrobić.

PS Nie rozumiem też dlaczego dla \(\displaystyle{ y=1}\) program się zawiesza.
Gouranga
Użytkownik
Użytkownik
Posty: 1592
Rejestracja: 16 maja 2013, o 17:56
Płeć: Mężczyzna
Lokalizacja: Trójmiasto
Podziękował: 11 razy
Pomógł: 246 razy

[C++] Sprawdzanie czy wśród liczb są naturalne

Post autor: Gouranga »

Jeśli nie potrafisz zrozumieć czyjegoś kodu to napisz swój od podstaw.
Jeśli nie potrafisz napisać swojego kodu to rozważ zmianę kierunku studiów.
matemix
Użytkownik
Użytkownik
Posty: 465
Rejestracja: 10 cze 2008, o 19:38
Płeć: Mężczyzna
Lokalizacja: Wrocław
Podziękował: 12 razy
Pomógł: 1 raz

[C++] Sprawdzanie czy wśród liczb są naturalne

Post autor: matemix »

Gouranga pisze:Jeśli nie potrafisz zrozumieć czyjegoś kodu to napisz swój od podstaw.
Jeśli nie potrafisz napisać swojego kodu to rozważ zmianę kierunku studiów.
Skończyłem już studia A jedyną styczność z programowaniem, jeśli chodzi o kilka kierunków, które studiowałem miałem na astronomii i były to podstawy programowania w C. Te podstawy wystarczały mi do pisania prostych programów, przy okazji niektórych zagadnień, które badałem (np. obliczanie iteracji różnych funkcji rekurencyjnych itp.).

Może napiszę swój program od podstaw, kiedyś lub za jakiś czas. Na dziś, dopóki ten działa zamierzam go tylko zmodyfikować.
ODPOWIEDZ