Форум программистов, компьютерный форум, киберфорум
Assembler: DOS/Real Mode/16-bits
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.68/37: Рейтинг темы: голосов - 37, средняя оценка - 4.68
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82

Разбор программы "Архиватор"

06.07.2013, 14:54. Показов 7501. Ответов 66
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток, ребят мне нужна помощь в программе, точнее прога есть, но не понимаю в ней(сижу в книгах разбираюсь, но получается долго).
Кто-нить помогите прокомментировать программу, так что бы было понятно(малость глуп)...
Спасибо!
Вложения
Тип файла: zip HUFFMAN.zip (6.3 Кб, 68 просмотров)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.07.2013, 14:54
Ответы с готовыми решениями:

Разбор программы
Вобщим я пытаюсь сделать для игры NOCD ексешник, что бы СД не запрашивало. Дизасемблировал код, где идет проверка на СД привод. Не могу...

Разбор программы
Всем доброго времени суток. Сестра просит объяснить что и как делает программа хотябы в общих шагах, но т.к. я пока полный 0 в ассемблере...

Архиватор данных - возможна ли оптимизация программы?
Привет! На С++ делаю конвертер видео в различные форматы. На входе несколько выбранных видеофайлов, на выходе столько же...

66
 Аватар для Troll_Face
608 / 406 / 8
Регистрация: 26.04.2012
Сообщений: 2,065
08.07.2013, 12:05
Студворк — интернет-сервис помощи студентам
sh2ezo, ну не знаю... перед асмом у меня был паскаль (на мой вгляд тупейший язык) и СИ++. вроде норм асм понимал...
1
08.07.2013, 14:20

Не по теме:

Цитата Сообщение от Troll_Face Посмотреть сообщение
паскаль (на мой вгляд тупейший язык)
Кхе... Зависит от реализации - MicroPower много чего умеет...
А вот язык Васик для компьтера "Ириша"(© МПСС,1989) я так и не освоил.

1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
11.07.2013, 21:00  [ТС]
сижу разбираюсь в данной проге: поймал исключение, точнее понял где оно происходит - в процедуре, но не понял где именно:
Assembler
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
FindNextParam   PROC    NEAR
;помещает в буфеp следующий паpаметp командной стpоки, и пеpедает его адpес
;в pегистpах DS:SI. Все кpайние пpобелы исключаются из стpоки. Паpаметp
;заканчивается символом 00h. Если паpаметp найден, то AL=1, если нет, то AL=0.
                PUSH    DS
                POP     ES
                LEA     DI, CmdLineBuffer
                MOV     CX, 32
                XOR     EAX, EAX
                REP  STOSD
                MOV     AH, 51h
                INT     21h
                MOV     FS, BX
                PUSH    DS
                POP     ES
                MOV     ParamFound, 0
                MOV     SI, CmdLinePointer
                DEC     SI
GetNext_1:      INC     SI
                CMP     SI, CmdLineEnd
                JZ      GetNext_3
                CMP     BYTE PTR FS:[SI], 32
                JZ      GetNext_1
                MOV     ParamFound, 1
                LEA     DI, CmdLineBuffer ;начинаем пеpедавать паpаметp в буфеp
GetNext_2:      MOV     AL, FS:[SI]
                CMP     AL, 32
                JZ      GetNext_3
                MOV     [DI], AL
                INC     DI
                INC     SI
                CMP     SI, CmdLineEnd
                JNZ     GetNext_2
GetNext_3:      MOV     CmdLinePointer, SI
                MOV     AL, ParamFound
                LEA     SI, CmdLineBuffer
                OR      AL, AL
                RET
FindNextParam   ENDP
если пробежать по программе через TD, то процедуру обрабатываем нормально, но после этой процедуры кидает в "пустоту", как я понял происходит исключение ... спустя пару операций в "пустоте" выдает ошибку "Divide by zero"

Добавлено через 4 часа 42 минуты
я понял прикол, это не исключение, у меня кажись память не так выделяется, в связи с чем TD стирает некоторые строки кода, стек данных стирает код как я понимаю...
всё дело в шапке программы:
Assembler
1
2
Cseg            SEGMENT USE16
                ASSUME  CS: Cseg, DS: Cseg, SS: Cseg
как изменить чтоб работало?)
0
 Аватар для Troll_Face
608 / 406 / 8
Регистрация: 26.04.2012
Сообщений: 2,065
12.07.2013, 08:12
Цитата Сообщение от bobibu Посмотреть сообщение
ASSUME CS: Cseg, DS: Cseg, SS: Cseg
это не код в его буквальном значении. Вы прогу как com собираете?
1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
12.07.2013, 08:18  [ТС]
не совсем понял вопрос(
0
 Аватар для Troll_Face
608 / 406 / 8
Регистрация: 26.04.2012
Сообщений: 2,065
12.07.2013, 08:30
может я что-то не так понял. после выхода из процедуры он поподает "в никуда"? вроде со стеком все в порядке, но попробуйте проследить за изменениями в стеке, чтобы все, что засунуто в стек было высуното.
1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
12.07.2013, 08:50  [ТС]
со стеком всё в порядке, да, но почему-то данные стека стирают код в TD:
Миниатюры
Разбор программы "Архиватор"  
0
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
12.07.2013, 14:06  [ТС]
закомментил строку:
;CALL FindNextParam
96 по счёту строка
и вроде программа отрабатывается норм в TD, но попрежнему не работает сама прога, так как она должна вывести на экран :
Huffman Encoder 1.0
Usage :
huffman.com a <source.ext> [dest.huf] - add to archive,
huffman.com e <source.huf> - extract from archive.
а потом мы должны водить...
..
но выдает пустую строку, вернее ничего не выдает...

Добавлено через 26 минут
выдает ошибку в конце отрабатываем проги
the ntvdm cpu has encountered an illegal instruction
Далее код ошибки
Chose 'Close' to terminate the application.
Добавлено через 4 часа 30 минут
беда со мной, че то не пашет...
или я не понимаю...
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PrintASCIIZ     PROC    NEAR
;prints string at ds:dx terminated with 00h
                PUSH    AX
                PUSH    BX
                PUSH    SI
                MOV     AH, 02h
                MOV     SI, DX
ASCIIZ_1:       MOV     DL, DS:[SI]
                OR      DL, DL
                JE      SHORT ASCIIZ_2
                INT     21h
                INC     SI
                JMP     SHORT ASCIIZ_1
ASCIIZ_2:       MOV     DX, SI
                POP     SI
                POP     BX
                POP     AX
                RET
PrintASCIIZ     ENDP
если быть точнее, то поясните по какому принцыпу работает участок:
Assembler
1
2
3
MOV     DL, DS:[SI]
                OR      DL, DL
                JE      SHORT ASCIIZ_2
у меня не пашет как надо строка
Assembler
1
OR      DL, DL
0
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
12.07.2013, 18:13
Блин, да ты-же эту программу как EXE компилируешь. А она-же написана как COM !

Добавлено через 10 минут
Цитата Сообщение от bobibu Посмотреть сообщение
не совсем понял вопрос(
А у "Юркина" об этом не было написано ?

Добавлено через 1 час 11 минут
P.S.
Посмотрел в учебник Юрова ASSEMBLER 2-е издание и ... действительно не написано.

Короче, компиляция COM-программы :
tasm /m/l proga.asm
tlink /t proga.obj
1
Ушел с форума
Автор FAQ
 Аватар для Mikl___
16373 / 7685 / 1080
Регистрация: 11.11.2010
Сообщений: 13,759
12.07.2013, 18:37
Цитата Сообщение от bobibu Посмотреть сообщение
у меня не пашет как надо строка
OR DL, DL
А как она должна "пахать"? идет проверка на равенство содержимого DS:[SI] нулю, если DS:[SI]=0 тогда будет переход на ASCIIZ_2 иначе вызывается 21h прерывание и происходит переход на следующий символ, на который указывает SI
1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
12.07.2013, 20:48  [ТС]
Ethereal, Большое спасибо, спрашивал у многих, все смотрели в код, но никто не понимал что компилить надо было com)))
всё сделал, программа работает, но появилась маленькая ошибка, точнее неправильно написано функция вызыва(как я понимаю):
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Begin_1:
                MOV     CodeSegment, DS
                MOV     SP, ProgramSize * 16 - 2
                CALL    GlobalMemAlloc
                LEA     DX, CopyrightMsg
                CALL    PrintASCIIZ
                CALL    FindFirstParam
                JZ      ShowUsage        <-------------------вот здесь
                CMP     BYTE PTR [SI], 'a'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'A'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'e'
                JE      SHORT CmdLine_Extract
                CMP     BYTE PTR [SI], 'E'
                JE      SHORT CmdLine_Extract
                JMP     ShowUsage
как правильно и грамматически исправить, а то пока издевался над кодом в неправильной компоновке, уже маленько побаиваюсь что-то исправлять, вдруг опять что...
Mikl___, теперь мне всё понятно, спасибо)
0
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
13.07.2013, 07:51
В чем неправильность по твоему мнению ?

У автора программы функция FindFirstParam возвращает результат во флаге Z
слова состояния процессора. Команда ret этих флагов не меняет, поэтому
можно выставить или сбросить какой-нибедь флажок в подпрограмме, тут-же
выйти из подпрограммы по ret, тогда во флажке окажется признак успешности
или не успешности отработки подпрограммы.

Процессор в твоей программе последовательно исполнит инструкции :
Code
1
2
3
4
5
6
7
8
                MOV     AL, ParamFound
                LEA     SI, CmdLineBuffer
                OR      AL, AL      ;Выставит флажок Z, если ParamFound = 0
                    ; и сбросит в противном случае
                RET         ;Не меняет флажок Z
                RET         ;Не меняет флажок Z
                JZ      ShowUsage   ;Переход, если выставлен флажок Z,
                    ; т.е. если ParamFound = 0
1
13.07.2013, 08:49

Не по теме:

Цитата Сообщение от bobibu Посмотреть сообщение
никто не понимал что компилить надо было com)))
Цитата Сообщение от Troll_Face Посмотреть сообщение
Вы прогу как com собираете?
какбывот

1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
13.07.2013, 22:48  [ТС]
Ethereal, спасибо за пояснение(лучше понял работу этой команды) , но ошибка маленько в другом месте, сейчас конкретнее поясню)
Assembler
1
2
3
4
5
6
7
                JZ      ShowUsage         <-----прыгает(если надо, а надо*)
                LEA     DX, UsageMsg      <-----сюды))
                CALL    PrintASCIIZ       <-----выводим строчки, затем функция 
                                          <-----должна была вернутся обратно 
                                          <-----в меню(Begin_1), но продолжает работать  
                CALL    GlobalMemFree     <-----переходя сюда
                INT     20h               <-----и наконец выходит из проги
сами функции работают хорошо)
но вот беда, программа выводит строчки:
Huffman Encoder 1.0
Usage :
huffman.com a <source.ext> [dest.huf] - add to archive,
huffman.com e <source.huf> - extract from archive.
и заканчивает работать, хотя должна сначала принять команду "что делать дальше"
ведь после
Assembler
1
                JZ      ShowUsage
идут строки проверки на дальнейшие операции:
Assembler
1
2
3
4
5
6
7
8
                CMP     BYTE PTR [SI], 'a'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'A'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'e'
                JE      SHORT CmdLine_Extract
                CMP     BYTE PTR [SI], 'E'
                JE      SHORT CmdLine_Extract
Цитата Сообщение от bobibu Посмотреть сообщение
как правильно и грамматически исправить, а то пока издевался над кодом в неправильной компоновке, уже маленько побаиваюсь что-то исправлять, вдруг опять что...
(я ведь всё правильно понял???)
(у вас программа идёт нормально???)
(у меня заканчивает работу после вывода строк с инф.)
0
 Аватар для Ethereal
6773 / 2741 / 385
Регистрация: 17.02.2013
Сообщений: 4,048
14.07.2013, 10:25
Если ты не задал программе параметры командной строки, то
JZ ShowUsage
сработает, управление улетит на метку ShowUsage, а там
код, который завершается
INT 20h <-----и наконец выходит из проги

Если ты задал программе корректные параметры командной строки, то
JZ ShowUsage
не сработает и тогда и только тогда выполнится
Code
1
2
3
4
5
6
7
8
                CMP     BYTE PTR [SI], 'a'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'A'
                JE      SHORT CmdLine_ADD
                CMP     BYTE PTR [SI], 'e'
                JE      SHORT CmdLine_Extract
                CMP     BYTE PTR [SI], 'E'
                JE      SHORT CmdLine_Extract
Добавлено через 5 минут
Цитата Сообщение от bobibu Посмотреть сообщение
Assembler
1
2
3
4
5
                JZ      ShowUsage         <-----прыгает(если надо, а надо*)
                LEA     DX, UsageMsg      <-----сюды))
                CALL    PrintASCIIZ       <-----выводим строчки, затем функция 
                                          <-----должна была вернутся обратно 
                                          <-----в меню(Begin_1), но продолжает работать
С чего бы это она должна вернуться обратно ?
И какое еще меню ?

Если ты не задал программе параметры командной строки, то она тебе
показывает Usage (ShowUsage) - как ее использовать и завершается.
Так и должно быть !
Если пользователь неправильно использует программу надо ему сказать
как это делать правильно и завершиться. Разве не так ?

Добавлено через 4 минуты
Внимательно читай эти строки
Usage :
huffman.com a <source.ext> [dest.huf] - add to archive,
huffman.com e <source.huf> - extract from archive.
пока не дойдет.
1
0 / 0 / 0
Регистрация: 13.06.2013
Сообщений: 82
14.07.2013, 10:58  [ТС]
Спасибо!!!!!!!!!!!
С вашей помощью до меня дошло!!!!!
Программа работает на ура!!!!!!!!!!!!!
0
programmer
 Аватар для Thread
2391 / 525 / 69
Регистрация: 01.06.2011
Сообщений: 3,639
20.07.2013, 08:18
помотрел код,но не пойму почему автор не использовал структуры для узлов?
По мне так это не самая лучшая реализация Хаффмана как по стилю,так и по коду.
Как он адаптивный реализовывал бы вобще не понятно.
0
 Аватар для Vadimych
639 / 482 / 12
Регистрация: 10.01.2011
Сообщений: 1,045
20.07.2013, 12:19
Цитата Сообщение от Thread Посмотреть сообщение
По мне так это не самая лучшая реализация Хаффмана как по стилю,так и по коду.

Не по теме:

Покажете свой вариант? Или предпочтёте остаться болтуном?

0
programmer
 Аватар для Thread
2391 / 525 / 69
Регистрация: 01.06.2011
Сообщений: 3,639
20.07.2013, 17:20
Теорию информацию не первый год изучаю.Реализовывал Хаффмана,адаптивный ренж кодер,JPEG2000,ENUC и еще куча всяких кодировщиков типа Хемминга и т.д.
Но увы на С/C++,не припомню чтобы на асме.Конкретно с деревьями работал по шахматной задаче,найти максимальное поражение фигур ходом коня за n шагов.Поэтому представление как работать с деревьями имею.
Второй момент,на асме пишу 7 лет.
этого достаточно,что бы понимать как должен выглядеть код для метода сжатия по Хаффману на асме?

Теперь вам вопрос.Что я не так сказал по поводу кода?Ваши аргументы.

Задача была своеобразной,но код расчитываеться префиксный с построением дерева.
Над оптимизацией кода сильно не заморачивался.

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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
#include <iostream>
#include <math.h>
using namespace std;
 
/*==================================================================
                Обьявление структур,массивов и переменных
==================================================================*/
 
struct  symbol{         //структура для символа
char    value;          //значение символа
float   prob;           //вероятность символа
char    code[256];      //префиксный код
symbol  *left;          //указатель на левый узел
symbol  *right;};       //указатель на правый узел
 
int     size_fr[256]={0};//частота встречаемости
int     count=0;        //сумма частот встречаемости
bool    flag;           //флаг выхода из цикла проверки на ошибку ввода
symbol  temp;           //временная-для промежуточного хранения результата
symbol  temp2;
int     sz_alphabet=1;
/*==================================================================
                Обьявление процедур и функций
==================================================================*/
 
symbol  *Tree(symbol*[],int);       //рекурсивная ф-ция создания дерева Хаффмана
float   L_sz(symbol [],int);            //среднее кол-во бит L на один код Хаффмана
float   H_sz(symbol [],int);            //среднее кол-во бит L на один код Хаффмана
void    Rand_str(char*,symbol*,char*,int ,symbol*[]);
void    Pref_code(symbol*);         //процедура получения кода узла
void    Encode(char*,char*,symbol*);//процедура кодирования
void    Decode(char*,char*,symbol*);//процедура декодирования
 
/*==================================================================
                Главная функция-точка входа в программу
==================================================================*/
 
int main(int argc,char* argv[])
{
//Отображение русского языка в консоле
setlocale(LC_ALL,"Russian"); 
 
//Задание и инициализация переменных
char *alphabet  = new char[256];    //массив для записи алфавита
short number_of_symbols=0;          //число символов в алфавите
char *bin_code  = new char[1000];   //массив для отображения бинарного закодированного кода
bin_code[0]=0;                      //для обозначения конца строки при первом присоединение к строке
char *encode_txt= new char[1000];   //текст для кодирования
char *decode_txt= new char[1000];   //восстановленный текст
 
float H;
float L;
symbol symbols[256]={0};            //инициализируем массив записей
symbol *addr_symbol[256];           //инициализируем массив указателей на записи
 
/*==================================================================
                Ввод алфавита и проверка на ошибки ввода
==================================================================*/
 
    do {
    flag=true;
    cout<<"Введите алфавит из 8-10 символов :   ";
    cin>>alphabet;
        if(strlen(alphabet)>7)
        {
            if(strlen(alphabet)<11)
            {
                sz_alphabet=strlen(alphabet);
                for (int i=0;i!=sz_alphabet;i++)
                {
                    for (int n=0;n!=sz_alphabet;n++)
                    {
                        if(alphabet[i]==alphabet[n])
                        {
                            if (i!=n)
                            {
                                cout <<"При задании алфавита встречены повторные символы!"<<endl;
                                cin.clear();           // Сбрасываем флаг ошибки
                                cin.ignore(255, '\n'); // Очищаем буфер
                                flag=false;
                            }
                        }
                        else flag=true;
                    if(!flag)break;
                    }
                if(!flag)break;
                }
            }
            else 
            {cout <<"Введенный алфавит состоит больше чем из 10 символов!"<<endl;
            flag=false;}
        }
        else 
        {cout <<"Введенный алфавит состоит меньше чем из 8 символов!"<<endl;
        flag=false;}
    }while (!flag);
    cout <<"Алфавит :    "<<alphabet<<endl;
 
/*==================================================================
                    Задаем таблицу частот символов
==================================================================*/
 
    for ( int i = 0; i < sz_alphabet; i++)
    {
        cout <<"Задайте частоту встречаемости для символа "<<alphabet[i]<<" :  ";
        cin>>size_fr[i];
        symbols[i].value=alphabet[i];
        count+=size_fr[i];
        if (!cin.good())
        {
            cin.clear();           // Сбрасываем флаг ошибки
            cin.ignore(255, '\n'); // Очищаем буфер
            cout<<"Введенный параметр не верен!"<<endl;
            i--;
        }
    }
    cout<<"Сумма частот встречаемости символов :    "<<count<<endl;
 
    Rand_str(alphabet,symbols,alphabet,sz_alphabet,addr_symbol);
 
    //вызов функции создания дерева Хаффмана   
    symbol * temp = Tree(addr_symbol,sz_alphabet);
    //вызов функции получения кода
    Pref_code(temp);
    //вызов функции расчета среднего количество бит L на один код Хаффмана
    L=L_sz(symbols,sz_alphabet);
    cout << "среднеe количество бит L на один код Хаффмана  : " <<L<< endl;
    //вызов функции расчета теоретического минимума бит на один код 
    H=H_sz(symbols,sz_alphabet);
    cout << "теоретический минимум бит на один код  : " <<H<< endl;
    if(L>=H)
    {
        cout << "Теоретические расчеты подтверждены : L >= H!!! " <<endl;
        cout << "Введите строку в соответствии с алфавитом и частотй символов : " <<endl;
        cin>>encode_txt;
    //функция кодирования строки
    Encode(encode_txt,bin_code,symbols);
    cout << "Закодированная строка : " << endl;
    cout << bin_code << endl;
    //функция декодирования строки
    Decode(bin_code,decode_txt, temp);
    cout << "Раскодированная строка : " << endl;
    cout << decode_txt << endl;
    }
    else 
    {
        cout << "L < H Ошибка вычисления!!! " <<endl;system("pause");
        return 0;
    }
 
    cout << "Введите произвольно строку битовой последовательности :   " <<endl;
    cin>>bin_code;
    Decode(bin_code,decode_txt, temp);
    cout << "Раскодированная строка : " << endl;
    cout << decode_txt << endl;
    delete alphabet;
    delete bin_code;
    delete decode_txt;
        system("pause");
        return 0;
        
}
 
/*==================================================================
                    Вспомогательные алгоритмы
==================================================================*/
 
//рекурсивная функция кодирования дерева
symbol *Tree(symbol *addr_symbol[],int number) 
{ 
    symbol *temp;
    temp = new symbol;
    temp->prob = addr_symbol[number-1]->prob+addr_symbol[number-2]->prob;
    temp->code[0] = 0;
    temp->left = addr_symbol[number-1];
    temp->right = addr_symbol[number-2];
    if ( number == 2 )
        return temp;
    else {
    //внесение в нужное место массива элемента дерева Хаффмана
      for (int i = 0; i < number; i++)
        if ( temp->prob > addr_symbol[i]->prob ) 
        {
          for(int j = number - 1; j > i; j--)
          { addr_symbol[j] = addr_symbol[j-1]; }
            
            addr_symbol[i] = temp;
            break;
        } 
    }
  return Tree(addr_symbol,number-1);
}
 
//ф-ия расчета среднего кол-ва бит L на один код Хаффмана
float L_sz(symbol symbols[],int number)
{
    float L=0;
    float *l=new float [number];
    for(int i=0;i<number;i++)
    {
        l[i]=0;
        for(int j=0;symbols[i].code[j]!=0;j++)
        {
        l[i]++;
        }
        l[i]*=symbols[i].prob;
    }
    for(int i=0;i<number;i++)
    {
        L+=l[i];
    }
    return L;
}
//ф-ия расчета теоретического минимума бит на один код 
float H_sz(symbol symbols[],int number)
{
    float H=0;
    float *l=new float [number];
    for(int i=0;i<number;i++)
    {
        l[i]=log(symbols[i].prob)/log(2.0);
        l[i]=-(l[i]*symbols[i].prob);
    }
    for(int i=0;i<number;i++)
    {
        H+=l[i];
    }
    return H;
}
//функция нахождения префиксного кода для узла
void Pref_code(symbol *temp) 
{ 
  if ( temp->left ) {
    strcpy(temp->left->code,temp->code);
    strcat(temp->left->code,"0");
    Pref_code(temp->left);
  }
  if ( temp->right ) {
    strcpy(temp->right->code,temp->code);
    strcat(temp->right->code,"1");
    Pref_code(temp->right);
  }
}
//функция кодирования строки
void Encode(char *encode_txt,char *bin_code,symbol *symbols)
{
    int tmp_symbol;
    for (int  i = 0; i < strlen(encode_txt); i++)
    {
        tmp_symbol = encode_txt[i];
        for (int  j = 0; j < strlen(encode_txt); j++)
        {
            if ( tmp_symbol == symbols[j].value )
            {
                strcat(bin_code,symbols[j].code);
            }
        }
    }
}
//функция декодирования строки
void Decode(char *bin_code,char *decode_txt,symbol *temp)
{
  symbol *present;// указатель в дереве
  char pr_bit;// значение текущего бита кода
  int number_of_bit;
  int pr_symbol;// индекс распаковываемого символа
  bool flag;  // флаг конца битовой последовательности
  flag = false;
  pr_symbol = 0;
  number_of_bit = 0;
  present = temp;
  //пока не закончилась битовая последовательность
  while ( number_of_bit != strlen(bin_code) ) {
    //пока не пришли в лист дерева
    while (present->left != NULL && present->right != NULL && 
           number_of_bit != strlen(bin_code) ) {
      //читаем значение очередного бита
      pr_bit = bin_code[number_of_bit++];
      //бит – 0, то идем налево, бит – 1, то направо
      if ( pr_bit == '0' ) 
        present = present->left;
      else 
        present = present->right;
    }
    //пришли в лист и формируем очередной символ
    decode_txt[pr_symbol++] = present->value;
    present = temp;
  }
  decode_txt[pr_symbol] = 0;
}
 
 
 
 
void Rand_str(char *encode_txt,symbol *symbols,char *alphabet,int number_of_symbols,symbol *addr_symbol[])
{
 
/*==================================================================
                    Расчет вероятностей символов
==================================================================*/
 
    for ( int i = 0; i < number_of_symbols; i++)
    {
        symbols[i].prob = (float)size_fr[i] / count;
        cout<<"Вероятность встречаемости символа "<<alphabet[i]<<" : "<<symbols[i].prob<<endl;
    }
 
/*==================================================================
                В массив указателей заносим адреса записей
==================================================================*/
 
    for ( int i = 0; i < number_of_symbols; i++) 
    addr_symbol[i] = &symbols[i];
 
/*==================================================================
                    Сортировка по убыванию 
==================================================================*/
symbol temp;
    for ( int i = 1; i < number_of_symbols; i++)
    {
        for ( int j = 0; j < number_of_symbols - 1; j++)
        {
            if ( symbols[j].prob < symbols[j+1].prob )
            {
            temp = symbols[j];
            symbols[j] = symbols[j+1];
            symbols[j+1] = temp;
            }
        }
    }
}
0
 Аватар для Vadimych
639 / 482 / 12
Регистрация: 10.01.2011
Сообщений: 1,045
20.07.2013, 18:43
Цитата Сообщение от Thread Посмотреть сообщение
на асме пишу 7 лет.
этого достаточно,что бы понимать как должен выглядеть код для метода сжатия по Хаффману на асме?
Thread, когда я увижу Ваше решение на асме, тогда смогу оценить достоинства Вашего стиля и кода. Сравнивать ассемблер и С++ не могу.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.07.2013, 18:43
Помогаю со студенческими работами здесь

После попытки скачать архиватор, не удаляются программы
После попытки скачать архиватор не удаляются программы через панель управления.Сообщение&quot;подождите пока анинсталлер...

Как из программы Java вызвать архиватор и заархивировать файл ?
Всем привет. Разобрался как открыть сторонним приложением любой файл, оказалось не сложно import java.io.IOException; public...

разбор программы
Друг написал прогу, но комментарии к ней не сделал, поэтому не понятно. Помогите разобраться с программой. Вот условие: Создать класс...

Разбор программы 2
Текст задачи №2 «Жизнь». Игра моделирует жизнь поколений гипотетической колонии живых клеток, которые выживают, размножаются или погибают...

Разбор программы
Здравствуйте! Помогите пожалуйста разобрать работу программы. Функция ее заключается в том что пользователь по построенному графу своей...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru