Форум программистов, компьютерный форум CyberForum.ru

Код Шеннона, не могу победить - C++

Восстановить пароль Регистрация
 
tchsa
0 / 0 / 1
Регистрация: 02.10.2014
Сообщений: 16
31.08.2015, 19:40     Код Шеннона, не могу победить #1
Привет всем! Делаю построение кода Шеннона. Не могу понять, где ошибка, на некоторых символах одинаковый код.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <vector>
#include <iomanip>
 
using namespace std;
 
class shennon{
public:
    double p;
    int count;
    char simb;
};
 
struct Compare{
public:
    bool operator()(const shennon* l, const shennon* r) const {
        return l->count > r->count;
    }
};
 
int main(){
    char *filename = "f";
    map <char, int> m;
    int numb_char = 0;
    char c;
 
    setlocale(LC_ALL, "Russian");
 
    ifstream infile(filename);
    if(!infile.is_open())
        cout << "Файл не может быть открыт!" << endl;
    else{
        while(!infile.eof()){
            c = infile.get();
            m[c]++;
            numb_char++;
        }
        infile.close();
    }
 
    list <shennon *> t;
    for(map <char, int>::iterator pItr = m.begin(); pItr != m.end(); pItr++){
        shennon *S = new shennon;
        S->p = (double)pItr->second / numb_char;
        S->simb = pItr->first;
        S->count = pItr->second;
        t.push_back(S);
    }
 
    t.sort(Compare());
 
    double q[38] = {0};
    int L[38] = {0};
    int csh[38][38] = {0};
    int i = 1;
    L[0] = 0;
    for(list <shennon *>::iterator pItr = t.begin(); pItr != t.end(); pItr++, i++){
        q[i] = q[i-1] + (*pItr)->p;     
        L[i] = (int)(-log((*pItr)->p) / log(2)+0.5);
    }
 
    for(int i = 1; i <= t.size(); i++){
        for(int j = 1; j <= L[i]; j++){
            q[i-1] = q[i-1] * 2;
            csh[i-1][j-1] = (int)q[i-1];
            if(q[i-1] > 1)
                q[i-1] = q[i-1] - 1;    
        }
    }
 
    i = 0;
    for(list <shennon *>::iterator pItr = t.begin(); pItr != t.end(); pItr++, i++){
        cout << "(" << setw(2) << L[i] << ") " << (*pItr)->simb << " : ";       
        for(int j = 0; j < L[i]; j++)
            cout << csh[i][j];
        cout << endl;
    }
 
    system("pause");
   return 0;
}
Код Шеннона, не могу победить
в примере символы "." и "f", "g" и "w" имеют одинаковый код.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.08.2015, 19:40     Код Шеннона, не могу победить
Посмотрите здесь:

Метод Шеннона фано C++
Метод Шеннона-Фано C++
C++ коды Фано, Хаффмана, Хэмминга, Шеннона, код с проверкой на четность
C++ как победить Double? Float?
C++ Алгоритм шеннона фано
C++ Ошибка времени выполнения Не могу понять как победить
Алгоритм Шеннона-Фано C++
Кодирование Шеннона-Фано C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kuzia domovenok
 Аватар для Kuzia domovenok
1883 / 1738 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
31.08.2015, 20:09     Код Шеннона, не могу победить #2
как это запустить? Файл имеется?
почему бы тебе не вывести промежуточные результаты? Например, значения q[i]
одинаковые ли они для ошибочных символов?
И вообще, правильно ли они считаются?
tchsa
0 / 0 / 1
Регистрация: 02.10.2014
Сообщений: 16
01.09.2015, 13:54  [ТС]     Код Шеннона, не могу победить #3
Промежуточные результаты выводил, просто убрал из кода, чтобы сократить. Вот весь код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <iostream>
#include <fstream>
#include <map>
#include <list>
#include <vector>
#include <iomanip>
 
using namespace std;
 
class shennon{
public:
    double p;
    int count;
    char simb;
};
 
struct Compare{
public:
    bool operator()(const shennon* l, const shennon* r) const {
        return l->count > r->count;
    }
};
 
int main(){
    char filename[30];
    map <char, int> m;
    int numb_char = 0;//кол-во символов в файле
    char c;//для хранения считываемого символа
    int s;
 
    setlocale(LC_ALL, "Russian");
    cout << "Введите имя файла: ";
    cin >> filename;
 
    ifstream infile(filename);
    if(!infile.is_open())
        cout << "Файл не может быть открыт!" << endl;
    else{
        while(!infile.eof()){ //пока не достигнут конец файла, считываем символы в map
            c = infile.get();
            //оставляем пробелы, все знаки препинания приводим к точке
            //все буквы малые
            s = (int)c;
            if(s >= 65 && s <= 90)
                s += 32;//преобразовываем в нижний регистр
            else if((s >= 33 && s <= 47) || (s >= 58 && s <= 64) || (s >= 91 && s <= 96))
                s = 46;//все знаки препинания приводим к точке
            else if(s > 122 || s < 32)
                continue;//не учитываем
            c = (char)s;
            m[c]++;
            numb_char++;//увеличиваем на один кол-во символов в файле
        }
        infile.close();
    }
 
    list <shennon *> t;
    for(map <char, int>::iterator pItr = m.begin(); pItr != m.end(); pItr++){
        shennon *S = new shennon;
        S->p = (double)pItr->second / numb_char;
        S->simb = pItr->first;
        S->count = pItr->second;
        t.push_back(S);
    }
 
    t.sort(Compare());
 
    for(list <shennon *>::iterator pItr = t.begin(); pItr != t.end(); pItr++){
        cout << (*pItr)->simb << " : " << (*pItr)->p << endl;
    }
    
    double q[38] = {0};
    int L[38] = {0};
    int csh[38][38] = {0};
    int i = 1;
    L[0] = 2;
    for(list <shennon *>::iterator pItr = t.begin(); pItr != t.end(); pItr++, i++){
        q[i] = q[i-1] + (*pItr)->p;     
        L[i] = (int)(-log((*pItr)->p) / log(2)+0.5);
        cout << (*pItr)->simb << " q[" << i << "] = " << q[i] << "     L[" << i << "] = " << L[i] << endl;
    }
 
    for(int i = 1; i <= t.size(); i++){
        for(int j = 1; j <= L[i]; j++){
            q[i-1] = q[i-1] * 2;
            csh[i-1][j-1] = (int)q[i-1];
            if(q[i-1] > 1)
                q[i-1] = q[i-1] - 1;    
        }
    }
 
    i = 0;
    for(list <shennon *>::iterator pItr = t.begin(); pItr != t.end(); pItr++, i++){
        cout << "(" << setw(2) << L[i] << ") " << (*pItr)->simb << " : ";       
        for(int j = 0; j < L[i]; j++)
            cout << csh[i][j];
        cout << endl;
    }
 
    system("pause");
   return 0;
}
f.txtНа этом файле проверяю.
Yandex
Объявления
01.09.2015, 13:54     Код Шеннона, не могу победить
Ответ Создать тему
Опции темы

Текущее время: 09:17. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru