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

Kodowanie arytmetyczne - liczby zmiennoprzecinkowe

Ostatnio zmodyfikowano 2014-05-27 22:12
Autor Wiadomość
damwes5
Temat założony przez niniejszego użytkownika
Kodowanie arytmetyczne - liczby zmiennoprzecinkowe
» 2014-05-27 10:31:40
Mam problem z prawidłowym przypisaniem zmiennych z tablicy typu float do zmiennej typu float/double.
Wynik wychodzi z kosmosu jak by znajdowały się gdzieś śmieci, kod poniżej:

C/C++
////// WYLICZENIE PRAWDOPODOBIENSTW  /////////
int i;
float prawd[ 900 ];
float sump[ 900 ];
float sumpp[ 900 ];
float dol;
float gora;
float podstawa;
float prawdo;
for( i = 0; i < t - 1; i++ )
{
   
   
    prawd[ i ] = ilosc[ i ] / ilosc_i;
    cout << znak[ i ] << " " << prawd[ i ] << endl;
}
sump[ 0 ] = 0;
for( i = 0; i < t; i++ )
{
   
   
    sump[ i + 1 ] = sump[ i ] + prawd[ i ];
   
}
for( i = 0; i < t; i++ )
{
   
    sumpp[ i ] = sump[ i ];
   
}

/////// ZNALEZIENIE PRZEDZIALU  ////////
//cout<<ilosc_i<<endl;


for( i = 0; i < ilosc_i; i++ )
{
    cout << "przedzial  : ";
   
    for( j = 0; j <= t - 1; j++ )
    {
        cout << " " << sumpp[ j ];
       
        cout << " -" << znak[ j ] << "-";
    }
   
    for( j = 0; j < t; j++ )
    {
       
        if( symbol[ i ] == znak[ j ] )
        {
            dol = sumpp[ j ];
            gora = sumpp[ j + 1 ];
           
            j = t;
           
        }
    }
   
    sump[ 0 ] = dol;
    sump[ t ] = gora;
    cout << endl;
    for( j = 1; j < t; j++ )
    {
        podstawa = gora - dol;
        sumpp[ j ] = sumpp[ j - 1 ] + prawd[ j - 1 ] * podstawa;
       
    }
P-110935
pekfos
» 2014-05-27 12:43:52
Jeśli t jest rozmiarem tablicy sump, nie możesz odwołać się tu do sump[j+1], ani w linii 30 do sump[t]. Podałeś za mało kodu, by nie zgadywać.. (cały podaj)
P-110939
damwes5
Temat założony przez niniejszego użytkownika
cała funkcja.
» 2014-05-27 14:47:14
Edytowałem kod i wkleiłem całą funkcję, po drobnych modyfikacjach. W takim razie jak powinienem ominąć problem ze stosem ?
P-110941
pekfos
» 2014-05-27 19:28:23
Z czym..?
P-110964
Moorfox
» 2014-05-27 19:58:36
Wklej resztę kodu to nie ma prawa się skompilować.
I jakim stosem ? Ten cały kod ma tylko jeden związek ze stosem i na pewno nie o to chodzi, chyba, że nie chcesz, żeby kompilator tworzył ci ramkę stosu, to wtedy przestań używać zmiennych lokalnych.
P-110967
damwes5
Temat założony przez niniejszego użytkownika
gotowy program.
» 2014-05-27 22:12:14
Udało mi się rozwiązać problem, poniżej kompresja pliku z zawartością do 10 znaków.. lipny algorytm, ale samo kodowanie działa.
C/C++
#include <cstdlib>
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <math.h>
#include <vector>
using namespace std;
/*
//////////////////////////////////////////////////////////////////////////////////////////////////
FUNKCJA ZLICZAJACA ILOSC WSZYSTKICH ZNAKOW

////////////////////////////////////////////////////////////////////////////////////////////////
*/

int lznakow( string nazwa_pliku_wejsciowego, ifstream & plik_odczyt, ofstream & plik_zapis ) //definicja funkcji wczytujacej/tworzacej pliki zliczającej ilosc znakow w pliku
{
    string tekst;
   
   
   
    plik_odczyt.open( nazwa_pliku_wejsciowego.c_str() );
   
   
    if( !plik_odczyt.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
    string t; //zmienna potrzebna do zliczenia znakow w wilu wierszach
   
    while( getline( plik_odczyt, tekst ) ) //zliczanie linii i laczenie tekstu
    {
        t = t + tekst;
       
    }
   
    int dlugosc = 0;
   
   
    for( int i = 1; t.length() >= i; i++ ) //petla zliczajaca ilosc znakow
    {
       
       
        dlugosc++;
    }
   
   
   
    cout << "\nilosc znakow w tekscie: " << dlugosc << endl;
   
   
   
   
    plik_zapis.open( "tekst.ile" );
   
   
    if( !plik_zapis.is_open() )
    {
        cout << "Blad otwierania pliku do zapisu w trybie tekstowym!" << endl;
        return - 1;
    }
   
    plik_zapis << dlugosc << " : tyle wynosi ilosc znakow w pliku "; //zapisanie do pliku ilosci znakow w tekscie
   
    while( true )
    {
       
        plik_odczyt >> tekst;
       
       
        if( !plik_odczyt.good() ) break;
       
        plik_zapis << tekst << endl;
       
       
    }
   
   
   
   
    plik_odczyt.close();
   
    plik_zapis.close();
   
    return 0;
}
/*
///////////////////////////////////////////////////////////////////////////////////////////
FUNKCJA ZLICZAJACA ILOSC POSZCZEGOLNYCH ZNAKOW

/////////////////////////////////////////////////////////////////////////////////////////

*/

int lznak( string nazwa_pliku_wejsciowego, ifstream & plik_odczyt, ofstream & plik_zapis )
{
   
   
    string tekst;
   
   
   
    plik_odczyt.open( nazwa_pliku_wejsciowego.c_str() );
   
   
    if( !plik_odczyt.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
   
   
    char zdanie[ 484000 ]; //tablica przechowująca wczytane zdanie
    int zlicz[ 127 ] = { }; //wyzerowania tablica przechowująca zliczenia liter
    int tmp = 0;
   
    while( !plik_odczyt.eof() )
    {
        plik_odczyt >> zdanie[ tmp++ ];
    }
   
   
    int i = 0; //zmienna do poruszania po komórkach tablicy
   
    while( zdanie[ i ] ) //lub zdanie[i]!=0
    {
        ++zlicz[ zdanie[ i ] ]; //zliczanie znaków
        ++i;
    }
   
   
   
   
   
    plik_zapis.open( "tekst.model" );
   
   
    if( !plik_zapis.is_open() )
    {
        cout << "Blad otwierania pliku do zapisu w trybie tekstowym!" << endl;
        return - 1;
    }
   
    for( int i = 0; i < 127; i++ ) //wypisanie wystąpień znakow ASCII
    {
        if( zlicz[ i ] )
        {
            cout <<( char ) i << "  " << zlicz[ i ] << endl;
           
            plik_zapis <<( char ) i << "  " << zlicz[ i ] << endl; //zapisanie do pliku ilosci znakow w tekscie
        }
    }
    while( true )
    {
       
        plik_odczyt >> tekst;
       
       
        if( !plik_odczyt.good() ) break;
       
        plik_zapis << tekst << endl;
       
       
    }
   
   
   
   
    plik_odczyt.close();
   
    plik_zapis.close();
   
    return 0;
   
   
}
/*
///////////////////////////////////////////////////////////////////////////////
FUNKCJA SORTUJACA MALEJACO WYSTAPIENIA ZNAKOW

///////////////////////////////////////////////////////////////////////////////
*/

int sort( ifstream & plik_odczyt, ofstream & plik_zapis )
{
   
   
    string tekst;
   
   
   
    plik_odczyt.open( "tekst.model" );
   
   
    if( !plik_odczyt.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
    string znak[ 127 ];
    long long int ilosc[ 90000 ];
   
   
   
   
    int t = 0, j = 0;
    while( !plik_odczyt.eof() )
    {
        plik_odczyt >> znak[ j++ ] >> ilosc[ t++ ];
    }
    plik_odczyt.close();
   
    string tmpc;
    int tmp = 0;
    for( int p = 0; p < t; p++ )
    {
       
        for( int i = 0; i < t - 2; i++ )
        {
            if( ilosc[ i ] <= ilosc[ i + 1 ] )
           
            {
                tmp = ilosc[ i ];
                ilosc[ i ] = ilosc[ i + 1 ];
                ilosc[ i + 1 ] = tmp;
               
                tmpc = znak[ i ];
                znak[ i ] = znak[ i + 1 ];
                znak[ i + 1 ] = tmpc;
               
            }
        }
    }
   
   
   
   
    plik_zapis.open( "tekst.modelsort" );
   
   
    if( !plik_zapis.is_open() )
    {
        cout << "Blad otwierania pliku do zapisu w trybie tekstowym!" << endl;
        return - 1;
    }
   
   
   
   
   
    for( int i = 0; i < t - 1; i++ ) //wypisanie wystąpień znakow ASCII
    {
        plik_zapis << znak[ i ] << "  " << ilosc[ i ] << endl;
        cout << znak[ i ] << " " << ilosc[ i ] << endl;
    }
   
    while( true )
    {
       
        plik_odczyt >> tekst;
       
       
        if( !plik_odczyt.good() ) break;
       
        plik_zapis << tekst << endl;
       
       
    }
   
   
   
    plik_zapis.close();
    return 0;
}

/*
////////////////////////////////////////////////////////////////////////////////////////
KODOWANIE ARYTMETYCZNE


////////////////////////////////////////////////////////////////////////////////////////
*/

int art( string nazwa_pliku_wejsciowego, string nazwa_modelsort, ifstream & plik_odczyt_i, ifstream & plik_odczyt, ofstream & plik_zapis )
{
   
   
    string tekst;
   
   
    /////// DO ODCZYTYWANIA KOLEJNO ZNAKOW  /////////
   
   
    plik_odczyt.open( nazwa_pliku_wejsciowego.c_str() );
   
   
    if( !plik_odczyt.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
    char symbol[ 10000 ];
   
   
   
    int g = 0;
    while( !plik_odczyt.eof() )
    {
        plik_odczyt >> symbol[ g++ ];
       
    }
    plik_odczyt.close();
   
   
    /////////////////////
    plik_odczyt.open( nazwa_modelsort.c_str() );
   
   
    if( !plik_odczyt.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
    char znak[ 127 ];
    long long int ilosc[ 90000 ];
   
   
    int t = 0, b = 0;
    while( !plik_odczyt.eof() )
    {
        plik_odczyt >> znak[ b++ ] >> ilosc[ t++ ];
       
    }
    plik_odczyt.close();
   
    /////// WCZYTANIE DLUGOSCI Z PLIKU  //////////
   
    plik_odczyt_i.open( "tekst.ile" );
   
   
    if( !plik_odczyt_i.is_open() )
    {
        cout << "Blad otwierania pliku odczytywanego w trybie tekstowym!" << endl;
        return - 1;
    }
   
    double ilosc_i;
   
    plik_odczyt_i >> ilosc_i;
   
   
    plik_odczyt_i.close();
   
   
    ////// WYLICZENIE PRAWDOPODOBIENSTW  /////////
   
   
   
    vector < double > sump( 90000 );
    float prawd[ 10000 ];
    float dol;
    float gora;
    float podstawa;
    float prawdo;
    int j;
    int i;
   
    for( i = 0; i < t - 1; i++ )
    {
       
       
        prawd[ i ] = ilosc[ i ] / ilosc_i;
        cout << znak[ i ] << " " << prawd[ i ] << endl;
    }
   
   
   
    for( i = 0; i < ilosc_i; i++ )
    {
       
       
        sump[ i + 1 ] = sump[ i ] + prawd[ i ];
       
    }
   
   
   
    cout << endl;
    /////// ZNALEZIENIE PRZEDZIALU  ////////
    cout << "przedzialy w kazdej iteracji" << endl << endl;
   
    for( i = 0; i < ilosc_i; i++ )
    {
        cout << "przedzial  : ";
       
        for( j = 0; j <= t - 1; j++ )
        {
            cout << " " << sump[ j ];
           
            //cout<<" -"<<znak[j]<<"-";
        }
        cout << endl;
        // tu jest jeszcze dobrze
        for( j = 0; j < ilosc_i; j++ )
        {
           
            if( symbol[ i ] == znak[ j ] )
            {
                dol = sump[ j ];
                gora = sump[ j + 1 ];
               
                j = t;
               
            }
        } //tu jest dobrze sump[1]
       
       
        sump[ 0 ] = dol;
        sump[ topic id = "NULL" ] = gora;
        //i tu dobrze
        cout << endl;
        for( j = 1; j < ilosc_i; j++ )
        {
            podstawa = gora - dol;
            sump[ j ] = sump[ j - 1 ] + prawd[ j - 1 ] * podstawa;
           
        }
    }
   
    // ej no i tu dobrze
    cout << endl << "PRZEDZIAL DO ZAKODOWANIA " << endl;
    cout << sump[ 0 ] << " oraz " << sump[ topic id = "NULL" ];
   
   
    //////// KODOWANIE PRZEDZIALU ///////////////////
   
   
    float bin[ 20000 ];
    bin[ 0 ] = 0.5;
    for( i = 1; i < 20; i++ ) {
        bin[ i ] = bin[ i - 1 ] / 2;
    }
   
   
   
   
   
   
    plik_zapis.open( "tekst.artm" );
   
   
    if( !plik_zapis.is_open() )
    {
        cout << "Blad otwierania pliku do zapisu w trybie tekstowym!" << endl;
        return - 1;
    }
   
   
   
   
   
   
   
   
   
   
   
   
    cout << endl << "KODOWANIE..." << endl;
   
    float suma = 0;
    int wart = 1;
    i = 0;
    while( wart ) {
        if(( bin[ i ] + suma ) < gora ) {
            suma += bin[ i ];
            cout << "1";
            plik_zapis << "1";
        }
        else {
            cout << "0";
            plik_zapis << "0";
        }
        if( suma > dol )
        if( suma < gora )
             wart = 0;
       
        i++;
    }
    i--;
   
    while(( bin[ i ] + suma ) > gora ) {
        cout << "0";
        plik_zapis << "0";
        i++;
    }
    i++;
   
   
   
   
    while( true )
    {
       
        plik_odczyt >> tekst;
       
       
        if( !plik_odczyt.good() ) break;
       
        plik_zapis << tekst << endl;
       
       
    }
    plik_zapis.close();
   
    return 0;
   
   
}
/*
////////////////////////////////////////////////////////////////////////////////////////
GLOWNA FUNKCJA PROGRAMU

//////////////////////////////////////////////////////////////////////////////////////
*/

int main( int argc, char * argv[] )
{
    string nazwa_pliku_wejsciowego;
    string nazwa_modelsort;
   
    ifstream plik_odczyt;
    ofstream plik_zapis;
    ifstream plik_odczyt_i;
    int RetCode;
   
   
   
    if( argc < 3 )
    {
        cout << "Nie podano nazwy pliku jako parametru wejsciowego!" << endl;
        return - 1;
    }
   
   
   
    nazwa_pliku_wejsciowego = argv[ 2 ];
    nazwa_modelsort = argv[ 1 ];
   
    cout << endl;
   
    cout << "Realizacja zadania ze zliczaniem wszystkich znakow" << endl << endl;
   
    RetCode = lznakow( nazwa_pliku_wejsciowego, plik_odczyt, plik_zapis );
   
   
    if( RetCode ==- 1 ) return - 1;
   
    cout << endl;
   
   
    cout << endl;
    cout << "Realizacja zadania ze zwracaniem ilosci poszczegolnych znakow" << endl << endl;
   
    //wywołanie funkcji realizującej zadanie 2
    RetCode = lznak( nazwa_pliku_wejsciowego, plik_odczyt, plik_zapis );
   
    cout << endl;
   
   
    cout << endl;
    cout << "Posortowanie ilosci poszczegolnych znakow malejaco" << endl << endl;
   
    //wywołanie funkcji realizującej zadanie 2
    RetCode = sort( plik_odczyt, plik_zapis );
   
   
    cout << endl;
    cout << "Kodowanie arytmetyczne z *.modelsort " << endl << endl;
   
    //wywołanie funkcji realizującej zadanie 3
    RetCode = art( nazwa_pliku_wejsciowego, nazwa_modelsort, plik_odczyt_i, plik_odczyt, plik_zapis );
   
    cout << endl;
   
    //sprawdzenie wyniku wykonania funkcji
    if( RetCode ==- 1 )
         return - 1;
    else
         return 0;
   
}
[/i]
P-110984
« 1 »
  Strona 1 z 1