purebasic.info

PureBasic forum
Текущее время: Пн апр 06, 2020 7:00 pm

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу Пред.  1, 2
Автор Сообщение
СообщениеДобавлено: Пт мар 20, 2020 5:23 am 
Не в сети
профессор

Зарегистрирован: Вт май 13, 2014 4:12 am
Сообщений: 937
Благодарил (а): 100 раз.
Поблагодарили: 31 раз.
Пункты репутации: 5
AZJIO писал(а):
И это с просьбой помочь ускорить?

я не просил, да и код не мой
а ускорить любой код, так это нормальное желание, и ни кто ни кого не пытался раскручивать

AZJIO писал(а):
то скорее всего вы хотели похвалиться

да мне то чем хвастаться, код не мой
в инете нет правильной сортировки, даже на сайтах предлагающих сортировку
кому не надо правильно, делайте через.....

так и не понял в чём меня обвиняют


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб мар 21, 2020 12:31 am 
Не в сети
док
Аватар пользователя

Зарегистрирован: Вт янв 26, 2016 4:44 pm
Сообщений: 195
Благодарил (а): 73 раз.
Поблагодарили: 24 раз.
Пункты репутации: 4
Сергейчик писал(а):
...
Вот затести. :roll:
Код:
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
 
Procedure change()
  Protected adresslov.l=j*4;по массиву
 
 ;сохраним для уверенности регистры
  !push ebx
  !push edx
  !push ecx
  !push edi
!mov ecx,-4
!mov dword ebx,[a_c$];начальный адрес массива с словами
!mov dword edx,[a_a];массив символов замены
!cikl:
!add dword ecx,4
         !mov dword edi,[ebx+ecx];адреса слов в массиве по смещению
     !cmp word [edi],0
     !jz wuiti;если слово пустое или конец перестановки то выходим с цикла
         ;
          !cikl2:;меняем символы
           !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0
           !mov word ax,[edi]
           ;
           !mov word ax,[edx+eax];взять символ с массива по номеру предыдущего
           !mov word [edi],ax;вставить как замену предыдущего
           ;
           !add dword edi,2;перемистить указатель на следующий символ
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца строки то повторяем цикл замены символа  
     !wuiti:  
 !cmp dword ecx,[p.v_adresslov+16]
 !jnz cikl
 ;
 !pop edi
 !pop ecx
 !pop edx
 !pop ebx
EndProcedure
 



В общем на маленьком словаре разница не ощутима (таймер не может точно отсчитать). На пурике то 0 то 16, на асме то же самое.
При подключении большого словаря (20мб вместо 3мб, и двойном обращении к нему) разница видна: пурик - 180мс, асм - то 16 то 31.
АСМ Рулит!


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб мар 21, 2020 12:30 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
Подход нужно менять,загрузить словарь в память в ней сразу конвертировать с параллейной раскладкой в массив? :roll:


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб мар 21, 2020 2:25 pm 
Не в сети
док
Аватар пользователя

Зарегистрирован: Вт янв 26, 2016 4:44 pm
Сообщений: 195
Благодарил (а): 73 раз.
Поблагодарили: 24 раз.
Пункты репутации: 4
Сергейчик писал(а):
Подход нужно менять,загрузить словарь в память в ней сразу конвертировать с параллейной раскладкой в массив? :roll:

Так, загрузить словарь как данные с помощью ReadData(). Далее, разбивать данные на слова и слова раскладывать в массив, потом сортировка массива, потом запись в файл?
Так а чем это отличается от того что уже есть?

Или вместо того чтобы переписывать слова в памяти из одного места в другое, можно создать массив указателей и в элементы разложить адреса указывающие на начала слов, создать функцию быстрой сортировки слов через указатели, но в элементах массива менять местами только указатели, а не сами слова...

Или имеется в виду сортировка слов в памяти до раскладки в массив? Наверно сортировка без индексации (с помощью массива) очень тормозная будет...

Вообще, было бы классно сделать процедуру загрузки текста в строковый массив на чистом АСМе, она бы многим пригодилась.


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Сб мар 21, 2020 6:52 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
Да скорее надо делать сортировку через указатели. :roll:
в массив загрузить слова ?под строки же память нужна определённая в количестве символов.
изменил немного аналог предыдущего и вынес !xor eax,eax за цикл в предыдущей процедуре наверное тоже так надо.
Ps:любой открытый файл будет изменён по символьно на 0. :D

Код:
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
 
Global memtabliza.i
Global *Unicode.Unicode
memtabliza=AllocateMemory(131070); нужен файл ресурсов для замены по типу вашего массива
 
For *Unicode.Unicode=memtabliza To memtabliza+131068 Step 2
*Unicode\u=48
Next
 
Global kolihestvostrok.l
Procedure Convertaciysimvolov(*memory,*memorytabliza);одновременно считае количество строк как бы слова у вас в словаре построчно?
!push esi
!push edi
!mov dword esi,[p.p_memorytabliza+8]
!mov dword edi,[p.p_memory+8];начальный адрес символов в памяти
     !cmp word [edi],0
     !jz wuiti;если конец текста
           !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0
         !cikl3:;считаем строки ,также с возможностью замены символов #CRLF$
           !add dword [v_kolihestvostrok],1
         !cikl2:;меняем символы
           !mov word ax,[edi]
           ;
           !mov word ax,[esi+eax];взять символ с массива по номеру предыдущего
           !mov word [edi],ax;вставить как замену предыдущего
           ;
           !add dword edi,2;перемистить указатель на следующий символ
           ;
           !cmp dword [edi],0a000dh;CRLF
           !jz cikl3
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца текста то повторяем цикл замены символа  
     !wuiti:
!pop edi
 !pop esi
 !retn 8
EndProcedure
 
 
 
 
Procedure Open_File()
  Protected File.i, lenght.l, *MemoryID,OpenFile.s
  OpenFile=OpenFileRequester("Открыть файл", "", "*.txt, *.asm,*.pb|*.txt;*.asm;*.pb|All Files|*.*", 0)
 If OpenFile<>""
    ;===============================                                                                                                  
 
  File = ReadFile(#PB_Any,OpenFile)
  If File ;если файл открыт идём дальше
       lenght = Lof(File);присвоем переменной количество байт текста в файле
    If lenght;если файл не пустой и имеет байты текста идем дальше
      *MemoryID=AllocateMemory(lenght+2);выделяем память под символы текста
      If *MemoryID ;если память выделена идём дальше
        ReadData(File,*MemoryID,lenght);
        CloseFile(File)
     ;  Debug PeekU(*MemoryID)
        Convertaciysimvolov(*MemoryID,memtabliza);замена символов
        ;  Debug PeekU(*MemoryID)
         
       
       Protected Dim adresastrok.i(kolihestvostrok);или тоже сразу занести в излишний массив или по новой пробежать расставить?
       ;вообще по уму файл использовать с заголовком и заранее знать к примеруколичество строк
       ;но кто знает как вы в файл словаря вставляете слова да ещё и построчно как бы любой текст незанесёшь так и нужна процедура переноса слов построчно
       ;дальше сортировка
       
        NomerFile =CreateFile(#PB_Any,OpenFile)
         If NomerFile
   
           WriteData(NomerFile,*MemoryID,lenght)
           
           CloseFile(NomerFile)
         Else
           MessageRequester("Запись файла","Не удалось сохранить файл!")
         EndIf
       
       
         FreeMemory(*MemoryID)
         ;CloseFile(File)
      EndIf
     EndIf
   EndIf
 EndIf  
EndProcedure
 
Open_File()
;Debug PeekU(mem+654)
 
FreeMemory(memtabliza)
 


Доработал ошибки и дошёл до сортировки. :roll:
Код:
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
 
Global memtabliza.i
Global *Unicode.Unicode
memtabliza=AllocateMemory(131070); нужен файл ресурсов для замены по типу вашего массива
 
For *Unicode.Unicode=memtabliza To memtabliza+131068 Step 2
*Unicode\u=48
Next
*Unicode.Unicode=memtabliza;оставим перевод строки он нам ненужен для смены ведь ещё есть операции с строками а это метка конца строки, вообще тогда проскачить лучше
;при конвертации её
*Unicode+18
*Unicode\u=10
*Unicode+6
*Unicode\u=13
 
Global kolihestvostrok.l
Procedure Convertaciysimvolov(*memory,*memorytabliza);одновременно считае количество строк как бы слова у вас в словаре построчно?
!push esi
!push edi
!mov dword esi,[p.p_memorytabliza+8]
!mov dword edi,[p.p_memory+8];начальный адрес символов в памяти
     !cmp word [edi],0
     !jz wuiti;если конец текста
           !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0
         !cikl3:;считаем строки ,также с возможностью замены символов #CRLF$
           !add dword [v_kolihestvostrok],1
         !cikl2:;меняем символы
           !mov word ax,[edi]
           ;
           !mov word ax,[esi+eax*2];взять символ из памяти таблицы по смещению номера
           !mov word [edi],ax;вставить как замену предыдущего
           ;
           !add dword edi,2;перемистить указатель на следующий символ
           ;
           !cmp dword [edi],0a000dh;CRLF
           !jz cikl3
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца текста то повторяем цикл замены символа  
     !wuiti:
!pop edi
 !pop esi
 !retn 8
EndProcedure
 
Procedure Adresastrok_tomassiv(*massivadresov,*MemID)
  !push edi
  !mov dword edi,[esp+8];адрес массива
  !mov dword eax,[esp+12];адрес строки
  !cmp word[eax],0
  !jz wyhod
  !mov dword [edi],eax
  !add dword edi,4
  !cikl6:
 !add dword eax,2
   !cmp word[eax],0
   !jz wyhod
   !cmp dword [eax],0a000dh;CRLF
   !jnz cikl6
   !add dword eax,4
   !cmp word[eax],0
   !jz wyhod
   !mov dword [edi],eax
   !add dword edi,4
   !jmp cikl6
  !wyhod:
  !pop edi
  !retn 8
EndProcedure
 
 
Procedure Open_File()
  Protected File.i, lenght.l, *MemoryID,OpenFile.s
  OpenFile=OpenFileRequester("Открыть файл", "", "*.txt, *.asm,*.pb|*.txt;*.asm;*.pb|All Files|*.*", 0)
 If OpenFile<>""
    ;===============================                                                                                                  
 
  File = ReadFile(#PB_Any,OpenFile)
  If File ;если файл открыт идём дальше
       lenght = Lof(File);присвоем переменной количество байт текста в файле
    If lenght;если файл не пустой и имеет байты текста идем дальше
      *MemoryID=AllocateMemory(lenght+2);выделяем память под символы текста
      If *MemoryID ;если память выделена идём дальше
        ReadData(File,*MemoryID,lenght);
        CloseFile(File)
     ;  Debug PeekU(*MemoryID)
        Convertaciysimvolov(*MemoryID+2,memtabliza);замена символов+2 для пропуска заголовка обозначения кодировки юникода у нас файл как бы в ней и мы неопрнделяем её
        ;  Debug PeekU(*MemoryID)
         
       
       Protected Dim massivadresovstrok.i(kolihestvostrok);или тоже сразу занести в излишний массив или по новой пробежать расставить?
       ;вообще по уму файл использовать с заголовком и заранее знать к примеруколичество строк
       ;но кто знает как вы в файл словаря вставляете слова да ещё и построчно как бы любой текст незанесёшь так и нужна процедура переноса слов построчно
       ;дальше сортировка
       ;допустим пойдем путём раскладки адресов после подсчёта строк
       Adresastrok_tomassiv(@massivadresovstrok(0),*MemoryID)
      ; Debug PeekU(massivadresovstrok(0))
       ;Debug PeekS(massivadresovstrok(0),-1,#PB_Unicode)
       ;Debug PeekU(massivadresovstrok(1))
       ;Debug PeekS(massivadresovstrok(1),-1,#PB_Unicode)
       
        NomerFile =CreateFile(#PB_Any,OpenFile)
         If NomerFile
   
           WriteData(NomerFile,*MemoryID,lenght)
           
           CloseFile(NomerFile)
         Else
           MessageRequester("Запись файла","Не удалось сохранить файл!")
         EndIf
       
       
         FreeMemory(*MemoryID)
         ;CloseFile(File)
      EndIf
     EndIf
   EndIf
 EndIf  
EndProcedure
 
Open_File()
;Debug PeekU(mem+654)
 
FreeMemory(memtabliza)
 


Pps:Вообще интересно как читает функция построчно из файла?
если она также каждый раз бежит выискивая метку конца строки(наверное так и есть),то эта операция растёт по времени в геометрической прогрессии с каждой новой отдалённой строкой от начала файла, и поэтому объясняет ваше время загрузки в массив = пробежать найти её позицию и после ещё выполнить конкатенацию переноса. :?
Поэтому наверное да мы пойдём своим путём. :roll:


Последний раз редактировалось Сергейчик Вс мар 22, 2020 11:05 am, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 12:05 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
Да уж дошёл до сортировки,объясните сергей ваш результат от сортировки,не нравится что то мне она..... :roll:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
Global Dim massivadresovstrok.s(10)
 
massivadresovstrok(0)="ёж"
massivadresovstrok(1)="ёжащий"
massivadresovstrok(2)="ёжащийся"
massivadresovstrok(3)="ёжик"
massivadresovstrok(4)="ёжиком"
massivadresovstrok(5)="ёжистый"
SortArray(massivadresovstrok(), #PB_Sort_Ascending|#PB_Sort_NoCase)
 
 
For i=0 To 5
Debug massivadresovstrok(i)
 
Next
 
 



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 7:48 am 
Не в сети
профессор

Зарегистрирован: Вт май 13, 2014 4:12 am
Сообщений: 937
Благодарил (а): 100 раз.
Поблагодарили: 31 раз.
Пункты репутации: 5
напомню на всякий случай, этот флаг #PB_Sort_NoCase не работает с русским текстом, в любом случае сортирует с учётом регистра


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 11:10 am 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
newJS писал(а):
напомню на всякий случай, этот флаг #PB_Sort_NoCase не работает с русским текстом, в любом случае сортирует с учётом регистра


Выявилось что не работает сортировка без указания номерации массива со строками,а с флагом незаморачиваюсь.
осталось процедурку написать одну. :roll:


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 12:04 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
Оказалось другую нужно процедуру написать типа конкатенации массива в память потому как функция сортировки
делает как как написал сергей (тосует адреса строк в массиве). :roll:
Код:
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
 
Global memtabliza.i
Global *Unicode.Unicode
memtabliza=AllocateMemory(131070); нужен файл ресурсов для замены по типу вашего массива
Global r.i
For *Unicode.Unicode=memtabliza To memtabliza+131068 Step 2
  *Unicode\u=Asc(Chr(r))
  r+1
Next
;*Unicode.Unicode=memtabliza;оставим перевод строки он нам ненужен для смены ведь ещё есть операции с строками а это метка конца строки, вообще тогда проскачить лучше
;;при конвертации её
;*Unicode+18
;*Unicode\u=10
;*Unicode+6
;*Unicode\u=13
 
Global Dim massivadresovstrok.s(0)
Global kolihestvostrok.l
Procedure Convertaciysimvolov(*memory,*memorytabliza);одновременно считаем количество строк как бы слова у вас в словаре построчно?
!push esi
!push edi
!mov dword esi,[p.p_memorytabliza+8]
!mov dword edi,[p.p_memory+8];начальный адрес символов в памяти
     !cmp word [edi],0
     !jz wuiti;если конец текста
           !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0
         !cikl3:;считаем строки ,также с возможностью замены символов #CRLF$
           !add dword [v_kolihestvostrok],1
         !cikl2:;меняем символы
           !mov word ax,[edi]
           ;
           !mov word ax,[esi+eax*2];взять символ с массива по номеру предыдущего
           !mov word [edi],ax;вставить как замену предыдущего
           ;
           !add dword edi,2;перемистить указатель на следующий символ
           ;
           !cmp dword [edi],0a000dh;CRLF
           !jz cikl3
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца текста то повторяем цикл замены символа  
     !wuiti:
!pop edi
 !pop esi
 !retn 8
EndProcedure
 
Procedure Adresastrok_tomassiv(*MemID)
  !push edi
  !mov dword edi,[a_massivadresovstrok];адрес массива
  !mov dword eax,[esp+8];адрес строки
  !cikl7:
 !cmp word[eax],0
  !jz wyhod
  !mov dword [edi],eax
  !add dword edi,4
  ;
   !cmp dword [eax],0a000dh;CRLF
   ;!cmp word [eax],13;CR;LF
   !jnz cikl6
   !mov dword [eax],0;;;;;;вставим 0000-конца строки подменив crLF иначе каламбур в строковом массиве
   !add dword eax,4
  ; !mov dword edi,eax
   ;!add dword edi,4
   !jmp cikl7
   
   !cikl6:
   !cmp word[eax],0
   !jz wyhod
   !add dword eax,2
   ;
   !cmp dword [eax],0a000dh;CRLF
   ;!cmp word [eax],13;CR;LF
   !jnz cikl6
   !cikl8:
  !mov dword [eax],0;;;вставим 0000-конца строки подменив crLF
   !add dword eax,4
   !cmp word[eax],0
   !jz wyhod
   !mov dword [edi],eax;запишем адрес новой строки
   !add dword edi,4
    !cmp dword [eax],0a000dh;CRLF
   ;!cmp word [eax],13;CR;LF
   !jnz cikl6
   !jmp cikl8
  !wyhod:
  !pop edi
  !retn 4
EndProcedure
 
Procedure vosstanovleniecrlf(*memm,kolihestvostrokk.l)
  !push edi
  !push ecx
  !mov dword edi,[esp+12];адрес массива
  !sub dword edi,2
  !xor dword ecx,ecx
  !cikl11:
    !add dword edi,2
     !cmp dword [edi],0
     !jnz cikl11
     !mov dword [edi],0a000dh;CRLF
     !add dword edi,2
  !add dword ecx,1
  !cmp dword ecx,[esp+16]
  !jnz cikl11
    !pop ecx
    !pop edi
  !retn 8
EndProcedure
Procedure Open_File()
  Protected File.i, lenght.l, *MemoryID,OpenFile.s
  OpenFile=OpenFileRequester("Открыть файл", "", "*.txt, *.asm,*.pb|*.txt;*.asm;*.pb|All Files|*.*", 0)
 If OpenFile<>""
    ;===============================                                                                                                  
 
  File = ReadFile(#PB_Any,OpenFile)
  If File ;если файл открыт идём дальше
       lenght = Lof(File);присвоем переменной количество байт текста в файле
    If lenght;если файл не пустой и имеет байты текста идем дальше
      *MemoryID=AllocateMemory(lenght+2);выделяем память под символы текста
      If *MemoryID ;если память выделена идём дальше
        ReadData(File,*MemoryID,lenght);
        CloseFile(File)
     ;  Debug PeekU(*MemoryID)
        Convertaciysimvolov(*MemoryID+2,memtabliza);замена символов+2 для пропуска заголовка обозначения кодировки юникода у нас файл как бы в ней и мы неопрнделяем её
        ;  Debug PeekU(*MemoryID)
         
       
       ReDim massivadresovstrok(kolihestvostrok-1);или тоже сразу занести в излишний массив или по новой пробежать расставить?
       ;вообще по уму файл использовать с заголовком и заранее знать к примеруколичество строк
       ;но кто знает как вы в файл словаря вставляете слова да ещё и построчно как бы любой текст незанесёшь так и нужна процедура переноса слов построчно
       ;дальше сортировка
       ;допустим пойдем путём раскладки адресов после подсчёта строк подсовывая их в строковой массив
       Adresastrok_tomassiv(*MemoryID+2)
       
 
       ;Debug PeekS(massivadresovstrok(0),-1,#PB_Unicode)
       ;Debug PeekS(massivadresovstrok(1),-1,#PB_Unicode)
       SortArray(massivadresovstrok(),#PB_Sort_Ascending,0,kolihestvostrok-1)
       Debug massivadresovstrok(0)
       Debug massivadresovstrok(1)
       Debug massivadresovstrok(2)
       Debug massivadresovstrok(3)
       ;
       vosstanovleniecrlf(*MemoryID+2,kolihestvostrok-1)
       For i=0 To 500 Step 2
         Debug PeekU(*MemoryID+i)
       Next
       
       
        NomerFile =CreateFile(#PB_Any,OpenFile)
         If NomerFile
   
           WriteData(NomerFile,*MemoryID,lenght)
           
           CloseFile(NomerFile)
         Else
           MessageRequester("Запись файла","Не удалось сохранить файл!")
         EndIf
       
       
         FreeMemory(*MemoryID)
         ;CloseFile(File)
      EndIf
     EndIf
   EndIf
 EndIf  
EndProcedure
 
Open_File()
;Debug PeekU(mem+654)
 
FreeMemory(memtabliza)
 



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 6:48 pm 
Не в сети
профессор

Зарегистрирован: Пн июл 22, 2013 11:00 pm
Сообщений: 972
Благодарил (а): 2 раз.
Поблагодарили: 55 раз.
Пункты репутации: 9
Кривовато но сортирует(слова должны быть обязательно в юникоде(utf16)с переносом строки,в конце тоже один) :roll:
Код:
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
 
Global memtabliza.i
Global *Unicode.Unicode
memtabliza=AllocateMemory(131072); нужен файл ресурсов для замены по типу вашего массива
Global r.i
For *Unicode.Unicode=memtabliza To memtabliza+131070 Step 2
  *Unicode\u=Asc(Chr(r))
  r+1
Next
;*Unicode.Unicode=memtabliza;оставим перевод строки он нам ненужен для смены ведь ещё есть операции с строками а это метка конца строки, вообще тогда проскачить лучше
;;при конвертации её
;*Unicode+18
;*Unicode\u=10
;*Unicode+6
;*Unicode\u=13
 
Global Dim massivadresovstrok.s(0)
Global kolihestvoslov.l
Procedure Convertaciysimvolov(*memory,*memorytabliza);одновременно считаем количество строк как бы слова у вас в словаре построчно?
!push esi
!push edi
!mov dword esi,[p.p_memorytabliza+8]
!mov dword edi,[p.p_memory+8];начальный адрес символов в памяти
 
   !cmp word [edi],0
     !jz wuiti;если конец текста
     !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0  
     !zikll:
    !cmp dword [edi],0a000dh;CRLF
     !jnz pryhok
     !cikl3:
    !mov word [edi],0;ставим конец строки на cr
     !add dword edi,4
     !jmp zikll
     ;
      !pryhok:;
       !cmp word [edi],0
       !jz wuiti;если конец текста
        !add dword [v_kolihestvoslov],1;;считаем слова и отдельные символы
        !cikl2:
        ;меняем символы
           !mov word ax,[edi]
           !mov word ax,[esi+eax*2];взять символ с массива по номеру предыдущего
           !mov word [edi],ax;вставить как замену предыдущего
           !add dword edi,2;перемистить указатель на следующий символ
           ;
           !cmp dword [edi],0a000dh;CRLF
           !jz cikl3
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца текста то повторяем цикл замены символа  
     !wuiti:
!pop edi
 !pop esi
 !retn 8
EndProcedure
 
Procedure Adresaslov_tomassiv(*MemID)
  !push edi
  !mov dword edi,[a_massivadresovstrok];адрес массива
  !mov dword eax,[esp+8];адрес строки
  !cikl7:
    !cmp dword [eax],0a0000h;00LF
     !jnz cikl6
     !zikl5:
    !add dword eax,4
     !jmp cikl7
     ;
    !cikl6:
      !cmp word[eax],0
       !jz wyhod
    !mov dword [edi],eax
    !add dword edi,4
    !zikl4:
   !add dword eax,2
    !cmp dword [eax],0a0000h;(00LF=память)(LF00=в регистре)
    !jz zikl5
    !cmp word[eax],0
    !jnz zikl4
  !wyhod:
  !pop edi
  !retn 4
EndProcedure
 
Procedure vosstanovleniecrlf(*memm,kolihestvostrokk.l)
  !push edi
  !push ecx
  !mov dword edi,[esp+12];адрес массива
  !sub dword edi,2
  !xor dword ecx,ecx
  !cikl11:
    !add dword edi,2
     !cmp dword [edi],0
     !jnz cikl11
     !mov dword [edi],0a000dh;CRLF
     !add dword edi,2
  !add dword ecx,1
  !cmp dword ecx,[esp+16]
  !jnz cikl11
    !pop ecx
    !pop edi
  !retn 8
EndProcedure
Procedure massiv_tomemory(*memm,kolstrok.i);не рабочая
 
  !push esi
  !push edi
  !push ebx
  !push ecx
  !mov dword ebx,[a_massivadresovstrok];адрес массива
  !mov dword edi,[esp+20];адрес memory
  !xor dword ecx,ecx
  !cikcl1:
   !mov dword esi,[ebx]
   !cikcl2:
    !mov word ax,[esi]
     !mov word [edi],ax
     !add dword edi,2
     !add dword esi,2
     !cmp dword [edi],10;00LF;дошли до конца строки
     !jnz cikcl2
     !mov word [edi-2],13;crLF
     !add dword edi,2
     
    !add dword ebx,4
  !add dword ecx,1
  !cmp dword ecx,[esp+24]
  !jnz cikcl1
    !mov word [edi],0
    !pop ecx
    !pop ebx
    !pop edi
    !pop esi
  !retn 8
EndProcedure
Procedure massiv_tomemory2(*memm,kolstrok.i)
  Protected *Unicode.unicode
  Protected *Unicode2.unicode=*memm
  Protected u.u
  For i=0 To kolstrok-1
    *Unicode.unicode=@massivadresovstrok(i)
   povtor:
   If *Unicode\u=10
     *Unicode2\u=10
      *Unicode2-2
      *Unicode2\u=13
      *Unicode2+4
    Else
      u=*Unicode\u
      *Unicode2\u=u
      *Unicode2+2
      *Unicode+2
      Goto povtor
   EndIf
  Next  
EndProcedure
Procedure Open_File()
  Protected File.i, lenght.l, *MemoryID,OpenFile.s
  OpenFile=OpenFileRequester("Открыть файл", "", "*.txt, *.asm,*.pb|*.txt;*.asm;*.pb|All Files|*.*", 0)
 If OpenFile<>""
    ;===============================                                                                                                  
 
  File = ReadFile(#PB_Any,OpenFile)
  If File ;если файл открыт идём дальше
       lenght = Lof(File);присвоем переменной количество байт текста в файле
    If lenght;если файл не пустой и имеет байты текста идем дальше
      *MemoryID=AllocateMemory(lenght+2);выделяем память под символы текста
      If *MemoryID ;если память выделена идём дальше
        ReadData(File,*MemoryID,lenght);
        CloseFile(File)
        ;  Debug PeekU(*MemoryID)
       ;ShowMemoryViewer(*MemoryID,500)
        Convertaciysimvolov(*MemoryID+2,memtabliza);замена и посчёт символов+2 для пропуска заголовка обозначения кодировки юникода у нас файл как бы в ней и мы неопрнделяем её
        ;  Debug PeekU(*MemoryID)
        ; ShowMemoryViewer(*MemoryID,500)
       
       ReDim massivadresovstrok(kolihestvoslov);или тоже сразу занести в излишний массив или по новой пробежать расставить?
       ;вообще по уму файл использовать с заголовком и заранее знать к примеруколичество строк
       ;но кто знает как вы в файл словаря вставляете слова да ещё и построчно как бы любой текст незанесёшь так и нужна процедура переноса слов построчно
       ;дальше сортировка
       ;допустим пойдем путём раскладки адресов после подсчёта строк подсовывая их в строковой массив
       Adresaslov_tomassiv(*MemoryID+2)
       
       SortArray(massivadresovstrok(),#PB_Sort_Ascending,0,kolihestvoslov-1)
       
       For i=0 To kolihestvoslov-1
       Debug massivadresovstrok(i)
       Next
       
       ;
    Protected *MemoryID2=AllocateMemory(lenght+6)
       PokeU(*MemoryID2,$feff);кодировка;похоже writedata сама пишет?
      massiv_tomemory2(*MemoryID2+2,kolihestvoslov)
 
       Debug PeekS(*MemoryID2,-1,#PB_Unicode)
       
        NomerFile =CreateFile(#PB_Any,OpenFile,#PB_File_SharedWrite)
         If NomerFile
   
           WriteData(NomerFile,*MemoryID2,lenght)
           
           CloseFile(NomerFile)
         Else
           MessageRequester("Запись файла","Не удалось сохранить файл!")
         EndIf
       
        FreeMemory(*MemoryID2)
         FreeMemory(*MemoryID)
         ;CloseFile(File)
      EndIf
     EndIf
   EndIf
 EndIf  
EndProcedure
 
Open_File()
;Debug PeekU(mem+654)
 
FreeMemory(memtabliza)
 


Ps:120 метров быстро без дебагера отсортировались за 5 секунд а блокнот открывал 3минуты. :D
Последний вариант с доработанной процедурой записи в память,сортирует строки слова ,вобщем создаём файл записываем слова или строки можно текст любой попробывать,сохраняем в юникоде и тестим. :roll:
Pps:замена стандартная равнозначным символом но до сортировки,можете изменить символы замены
или типа файла таблицы создать
Код:
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
 
Global memtabliza.i
Global *Unicode.Unicode
memtabliza=AllocateMemory(131072); нужен файл ресурсов для замены по типу вашего массива
Global r.i
For *Unicode.Unicode=memtabliza To memtabliza+131070 Step 2
  *Unicode\u=Asc(Chr(r))
  r+1
Next
;*Unicode.Unicode=memtabliza;оставим перевод строки он нам ненужен для смены ведь ещё есть операции с строками а это метка конца строки, вообще тогда проскачить лучше
;;при конвертации её
;*Unicode+18
;*Unicode\u=10
;*Unicode+6
;*Unicode\u=13
 
Global Dim massivadresovstrok.s(0)
Global kolihestvoslov.l
 
Procedure Convertaciysimvolov(*memory,*memorytabliza);одновременно считаем количество строк как бы слова у вас в словаре построчно?
!push esi
!push edi
!mov dword esi,[p.p_memorytabliza+8]
!mov dword edi,[p.p_memory+8];начальный адрес символов в памяти
 
   !cmp word [edi],0
     !jz wuiti;если конец текста
     !xor eax,eax;получить номер символа и расширить до .w до .i предварительно чистим для старших разрядов в 0  
     !zikll:
    !cmp dword [edi],0a000dh;CRLF
     !jnz pryhok
     !cikl3:
    !mov word [edi],0;ставим конец строки на cr
     !add dword edi,4
     !jmp zikll
     ;
      !pryhok:;
       !cmp word [edi],0
       !jz wuiti;если конец текста
        !add dword [v_kolihestvoslov],1;;считаем слова и отдельные символы
        !cikl2:
        ;меняем символы
           !mov word ax,[edi]
           !mov word ax,[esi+eax*2];взять символ с массива по номеру предыдущего
           !mov word [edi],ax;вставить как замену предыдущего
           !add dword edi,2;перемистить указатель на следующий символ
           ;
           !cmp dword [edi],0a000dh;CRLF
           !jz cikl3
           !cmp word [edi],0
           !jnz cikl2;если не достигли (00)=указатель конца текста то повторяем цикл замены символа  
     !wuiti:
!pop edi
 !pop esi
 !retn 8
EndProcedure
 
Procedure Adresaslov_tomassiv(*MemID)
  !push edi
  !mov dword edi,[a_massivadresovstrok];адрес массива
  !mov dword eax,[esp+8];адрес строки
  !cikl7:
    !cmp dword [eax],0a0000h;00LF
     !jnz cikl6
     !zikl5:
    !add dword eax,4
     !jmp cikl7
     ;
    !cikl6:
      !cmp word[eax],0
       !jz wyhod
    !mov dword [edi],eax
    !add dword edi,4
    !zikl4:
   !add dword eax,2
    !cmp dword [eax],0a0000h;(00LF=память)(LF00=в регистре)
    !jz zikl5
    !cmp word[eax],0
    !jnz zikl4
  !wyhod:
  !pop edi
  !retn 4
EndProcedure
 
 
Procedure massiv_tomemory(*memm,kolstrok.i);не рабочая
  !mov dword eax,[esp+8]
  !imul dword eax,4
  !mov dword[esp+8],eax
  !push esi
  !push edi
  !push ebx
  !push ecx
  !mov dword ebx,[a_massivadresovstrok];адрес массива
  !mov dword edi,[esp+20];адрес memory
  !xor dword ecx,ecx
  !jmp cikclf1
  !ddf:
  !mov dword [edi],0a000dh
   !add dword edi,4
    !add dword ecx,4
    !cmp dword ecx,[esp+24]
    !jz gfrj
  !cikclf1:
   !mov dword esi,[ebx+ecx]
   !cikclf2:
   !cmp word [esi],0
     !jz ddf
    !dfs:
    !mov word ax,[esi]
     !mov word [edi],ax
     !add dword edi,2
     !add dword esi,2
     !cmp word [esi],0
     !jnz dfs
     !jz ddf
  !gfrj:
   !mov word [edi],0
    !pop ecx
    !pop ebx
    !pop edi
    !pop esi
  !retn 8
EndProcedure
Procedure massiv_tomemory2(*memm,kolstrok.i)
  Protected *Unicode.unicode
  Protected *Unicode2.unicode=*memm
  Protected u.u
  For i=0 To kolstrok-1
    *Unicode.unicode=@massivadresovstrok(i)
   povtor:
   If *Unicode\u=0
     *Unicode2\u=13
      *Unicode2+2
      *Unicode2\u=10
      *Unicode2+2
    Else
      u=*Unicode\u
      *Unicode2\u=u
      *Unicode2+2
      *Unicode+2
      Goto povtor
   EndIf
  Next  
EndProcedure
Procedure Open_File()
  Protected File.i, lenght.l, *MemoryID,OpenFile.s
  OpenFile=OpenFileRequester("Открыть файл", "", "*.txt, *.asm,*.pb|*.txt;*.asm;*.pb|All Files|*.*", 0)
 If OpenFile<>""
    ;===============================                                                                                                  
 
  File = ReadFile(#PB_Any,OpenFile)
  If File ;если файл открыт идём дальше
       lenght = Lof(File);присвоем переменной количество байт текста в файле
    If lenght;если файл не пустой и имеет байты текста идем дальше
      *MemoryID=AllocateMemory(lenght+2);выделяем память под символы текста
      If *MemoryID ;если память выделена идём дальше
        ReadData(File,*MemoryID,lenght);
        CloseFile(File)
        ;  Debug PeekU(*MemoryID)
       ;ShowMemoryViewer(*MemoryID,500)
        Convertaciysimvolov(*MemoryID+2,memtabliza);замена и посчёт символов+2 для пропуска заголовка обозначения кодировки юникода у нас файл как бы в ней и мы неопрнделяем её
        ;  Debug PeekU(*MemoryID)
        ; ShowMemoryViewer(*MemoryID,500)
   If  kolihestvoslov>0    
       ReDim massivadresovstrok(kolihestvoslov);или тоже сразу занести в излишний массив или по новой пробежать расставить?
       ;вообще по уму файл использовать с заголовком и заранее знать к примеруколичество строк
       ;но кто знает как вы в файл словаря вставляете слова да ещё и построчно как бы любой текст незанесёшь так и нужна процедура переноса слов построчно
       ;дальше сортировка
       ;допустим пойдем путём раскладки адресов после подсчёта строк подсовывая их в строковой массив
       Adresaslov_tomassiv(*MemoryID+2)
       
       SortArray(massivadresovstrok(),#PB_Sort_Ascending,0,kolihestvoslov-1)
       
      ; For i=0 To kolihestvoslov-1
     ;  Debug massivadresovstrok(i)
      ; Next
       
  ;If  kolihestvoslov>0
    Protected *MemoryID2=AllocateMemory(lenght+6)
       PokeU(*MemoryID2,$feff);кодировка;похоже writedata сама пишет?
     
       massiv_tomemory(*MemoryID2+2,kolihestvoslov)
       Debug PeekS(*MemoryID2,-1,#PB_Unicode)
       
        NomerFile =CreateFile(#PB_Any,OpenFile,#PB_File_SharedWrite)
         If NomerFile
   
           WriteData(NomerFile,*MemoryID2,lenght)
           
           CloseFile(NomerFile)
         Else
           MessageRequester("Запись файла","Не удалось сохранить файл!")
         EndIf
       
         FreeMemory(*MemoryID2)
      EndIf  
         FreeMemory(*MemoryID)
         ;CloseFile(File)
      EndIf
     EndIf
   EndIf
 EndIf  
EndProcedure
 
Open_File()
;Debug PeekU(mem+654)
 
FreeMemory(memtabliza)
 



Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вс мар 22, 2020 11:34 pm 
Не в сети
док
Аватар пользователя

Зарегистрирован: Вт янв 26, 2016 4:44 pm
Сообщений: 195
Благодарил (а): 73 раз.
Поблагодарили: 24 раз.
Пункты репутации: 4
Сергейчик
Спасибо большое за Ваш труд! Я разберу каждый код через несколько дней, сейчас завал на работе...


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Вт мар 24, 2020 3:10 pm 
Не в сети
профессор

Зарегистрирован: Вс июл 05, 2009 5:55 pm
Сообщений: 392
Благодарил (а): 1 раз.
Поблагодарили: 17 раз.
Пункты репутации: 0
Я пока ничего не проверял, потому что инет на работе, а дома нужно ковыряться. Но тоже ковырялся с быстрой сортировкой, пытаясь разобрать как она так быстро работает. Я хотел сделать ещё быстрее, но облом.
Зато перлов насмотрелся.
Обычно коды быстрой сортировки для пурика да и так на великом Си пестрят ошибками. Например
1.при поиске меньшего или большего у них используется цикл без тормозов, что приводит к выходу за пределы массива.

2.Во вторых я так понял что если работать со строками и пуриковский странностями страдает.

3 сортировка пуриковским по порядку и когда приравниваются большие и маленькие буквы одинаковые, может это у меня такой глюк.

4 я переделал их быстрый сортировщик у которого есть недостаток когда он вызывает сам себя в процедуре что может приводить к переполнению стека.
В общем мне удалось сделать его без вызова процедуры самого себя. Но с проверками и переделками он стал немного тормознутей, но я думаю что если и обычный довести до ума то он не будет быстрее. Если обычный обрабатывает за 1 сек, то мой где-то за 1.4, но всё зависит от порядка в массиве, и это всегда имеет разный результат.
Анализируя грубину вхождений заметил более 20, а это уже не хило грузит стек. Он за одно вхождение передает туда два числа и минимум два адреса возврата, а это уже 16 байт и это не считая того что пурик свое сохраняет и это умножить на 20 будет 320. Мне интересно какая глубина стека сейчас, раньше их заботило превышение в 256 байт, но это какой-то мизер, прям нашли на чем с экономить.

4. В юникоде русская буква Ё имеет код 1025, а бука А 1040, благодаря чему ее забрасывает на начало сортировки. Поэтому тут нужно создавать свою таблицу перекодировки или прогонять массив на наличие буквы Ё и сортировать в нужное место.

5. Но меня больше всего удивил пуриковский сортировщик, его скорость превышают во много раз обычный быстрый код сортировки. Я пытаюсь понять что они туда запихали. И при этом дебуггер отключал, а то очень сильно заметно на скорость быстрого сортировщика влияет. Мне кажется что они использовали кеш таблицы.

_________________
искатель истины


Вернуться наверх
 Профиль  
 
СообщениеДобавлено: Чт мар 26, 2020 4:59 pm 
Не в сети
док
Аватар пользователя

Зарегистрирован: Вт янв 26, 2016 4:44 pm
Сообщений: 195
Благодарил (а): 73 раз.
Поблагодарили: 24 раз.
Пункты репутации: 4
Сергейчик писал(а):
Да уж дошёл до сортировки,объясните сергей ваш результат от сортировки,не нравится что то мне она..... :roll:
Код:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
Global Dim massivadresovstrok.s(10)
 
massivadresovstrok(0)="ёж"
massivadresovstrok(1)="ёжащий"
massivadresovstrok(2)="ёжащийся"
massivadresovstrok(3)="ёжик"
massivadresovstrok(4)="ёжиком"
massivadresovstrok(5)="ёжистый"
SortArray(massivadresovstrok(), #PB_Sort_Ascending|#PB_Sort_NoCase)
 
For i=0 To 5
Debug massivadresovstrok(i)
Next
 



Не совсем понял вопрос, но нужно подрезать хвост массива с нулевым содержимым, иначе в начале будут пустые строки.
У нас в коде после загрузки слов для этого просто ставим RеDIM()...

balex1978 писал(а):
4. В юникоде русская буква Ё имеет код 1025, а бука А 1040, благодаря чему ее забрасывает на начало сортировки. Поэтому тут нужно создавать свою таблицу перекодировки или прогонять массив на наличие буквы Ё и сортировать в нужное место

Ну, код выложенный в начале подразумевает подмену символов (типа каждому встреченному символу A, на время сортировки присваиваем код 1025, после сортировки возвращаем всё назад), так работает.
Цитата:
5. Но меня больше всего удивил пуриковский сортировщик, его скорость превышают во много раз обычный быстрый код сортировки. Я пытаюсь понять что они туда запихали. И при этом дебуггер отключал, а то очень сильно заметно на скорость быстрого сортировщика влияет. Мне кажется что они использовали кеш таблицы.


Цитата из справки:
Цитата:
Обратите внимание, что это не работает с Массивами, так как для сортировки Массивов Структурных и базовых типов используется нестабильный метод Quicksort (быстрая сортировка), то есть сортировка по вторичному ключу будет потеряна.

Вы сравнивали именно на строках? В смысле, при сортировке массива чисел тоже скорость больше чем у всех?


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 28 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: AZJIO, MSN [Bot] и гости: 3


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group (блог о phpBB)
Сборка создана CMSart Studio
Русская поддержка phpBB