IMStrelcov
CTPEJIbLLOB
- Сообщения
- 259
- Репутация
- 66
- Версия AutoIt
- 3.3.14.5
- Версия
- 0.1
Данный скрипт показывает более менее правильную сортировку в списке ListView
Прошу подсказать как можно ускорить код, так как время сортировки в 10000 строк в списке занимает около 30 секунд.
Может чегото не хватает или наоборот лишнее?
Так же можно предлагать свои примеры, идеи, на эту тему.
Сразу отвечу на пару вопросов которые могут возникнуть:
Прошу подсказать как можно ускорить код, так как время сортировки в 10000 строк в списке занимает около 30 секунд.
Может чегото не хватает или наоборот лишнее?
Так же можно предлагать свои примеры, идеи, на эту тему.
Сразу отвечу на пару вопросов которые могут возникнуть:
Зачем это нужно?
Всем, кто хоть раз копал инет по поводу алгоритмов сортировки, знает, что сортировка происходит по принципу или
1, 11, 9, 99, а, аа, в, вв или 1, 9, а, в, 11, 99, аа, вв.
Так вот в этом коде строки и цифры сортируются более менее адекватно, т.е.:
текст 1, текст 9, текст 11.
При сортировке стандартными способами было бы так:
текст 1, текст 11, текст 9.
Как отдается приоритет строкам и цифрам?
Каждая строка разбивается на группы последовательно идущих цифр, букв, и знаков, после чего строки сравниваются этими подгруппами.
Знаки имеют приоритет ниже чем цифры или буквы, поэтому строки начинающиеся на знаки всегда будут стоять выше всех строк.
Цифры имеют высший приоритет над знаками, но низший над буквами.
Буквы имеют высший приоритет над знаками и цифрами, и поэтому строки начинающиеся на букву будут стоять всегда ниже всех.
Почему в регулярном выражении не использовал [A-z] вместо перечисления букв?
Потому что при использовании [A-z] идет захват символа _ (нижнее подчеркивание), а это в моем понимании относится к знакам.
Будет ли дальше развиваться код в этом направлении?
Не знаю, все в ваших руках.
Я на это, что имею, убил более двух недель пока нашел и исправил косяки, еще месяц на реализацию в AutoIt-е алгоритмов разных сортировок, которые ни принесли нужного результата по скорости или требовали большего объема памяти для сортировки (только время отняло, хотя и опыта поднабрался).
Возможно в будущем и буду развивать эту тему, а пока времени нет.
Если есть толковые люди, а они есть, то прошу не стеснятся выкладывать свои идеи, обсуждать тему, а то форум смотрю вымирает, одни бото-кодеры развелись, которым то сделай или это.
Всем, кто хоть раз копал инет по поводу алгоритмов сортировки, знает, что сортировка происходит по принципу или
1, 11, 9, 99, а, аа, в, вв или 1, 9, а, в, 11, 99, аа, вв.
Так вот в этом коде строки и цифры сортируются более менее адекватно, т.е.:
текст 1, текст 9, текст 11.
При сортировке стандартными способами было бы так:
текст 1, текст 11, текст 9.
Как отдается приоритет строкам и цифрам?
Каждая строка разбивается на группы последовательно идущих цифр, букв, и знаков, после чего строки сравниваются этими подгруппами.
Знаки имеют приоритет ниже чем цифры или буквы, поэтому строки начинающиеся на знаки всегда будут стоять выше всех строк.
Цифры имеют высший приоритет над знаками, но низший над буквами.
Буквы имеют высший приоритет над знаками и цифрами, и поэтому строки начинающиеся на букву будут стоять всегда ниже всех.
Почему в регулярном выражении не использовал [A-z] вместо перечисления букв?
Потому что при использовании [A-z] идет захват символа _ (нижнее подчеркивание), а это в моем понимании относится к знакам.
Будет ли дальше развиваться код в этом направлении?
Не знаю, все в ваших руках.
Я на это, что имею, убил более двух недель пока нашел и исправил косяки, еще месяц на реализацию в AutoIt-е алгоритмов разных сортировок, которые ни принесли нужного результата по скорости или требовали большего объема памяти для сортировки (только время отняло, хотя и опыта поднабрался).
Возможно в будущем и буду развивать эту тему, а пока времени нет.
Если есть толковые люди, а они есть, то прошу не стеснятся выкладывать свои идеи, обсуждать тему, а то форум смотрю вымирает, одни бото-кодеры развелись, которым то сделай или это.
Код:
#NoTrayIcon
#include <WindowsConstants.au3>
#include <GuiListView.au3>
$aArray = '@,@1,@11,@9,@99,@a,@zz,@z,@aa,@@1,@@99,@@9,@@11,@@zz,@@aa,@@a,@@z,@№,@№№,№1,№11,№@@,№@,№aa,№a,№zz,№z,№9,№99,№,№№9,№№a,№№1,№№,№№z,№№11,№№zz,№№99,№№aa,1zz,1z,1,1№,1@,1a,1№№,19,1aa,199,1@@,9@,9a,91,9№№,9@@,9,9№,911,9zz,9z,9aa,11aa,11a,11№,119,11@,11z,11№№,1199,11zz,11,11@@,99№,99№№,99z,991,99zz,99@,99,9911,99aa,99@@,99a,a,a№№,a№,a11,a@,a99,az,a1,azz,a@@,a9,z99,z,z11,zaa,z1,z№№,z@,z9,z№,za,z@@,aa,aazz,aa@@,aa99,aaz,aa@,aa9,aa№№,aa11,aa1,aa№,zz1,zz№№,zz11,zz@@,zz,zzaa,zz№,zza,,zz@,zz99,zz9'
$aArray = StringSplit($aArray, ',', 3)
$iWnd = GUICreate('Test ListView', 800, 600, -1, -1, $WS_MAXIMIZEBOX +$WS_MINIMIZEBOX +$WS_SIZEBOX +$WS_VISIBLE, $WS_EX_ACCEPTFILES)
$iListView = _GUICtrlListView_Create($iWnd, '', 10, 10, 780, 555, BitOR($LVS_REPORT, $LVS_SHOWSELALWAYS, $WS_CHILD, $WS_VISIBLE))
_GUICtrlListView_AddColumn($iListView, 'Sort', 760)
$iTime = TimerInit()
For $a=0 To UBound($aArray) -1
_GUICtrlListView_AddItemSort($iListView, $aArray[$a])
Next
$iTime = TimerDiff($iTime)
ConsoleWrite('Time'&@TAB&@TAB&$iTime&@CRLF)
While 1
Switch GUIGetMsg()
Case -3
ExitLoop
EndSwitch
WEnd
Func _GUICtrlListView_AddItemSort(ByRef $_hWnd, ByRef $_sStrL)
Local $_iIndex = 0
Local $_iEnd = _GUICtrlListView_GetItemCount($_hWnd)
Local $_iBegin = 1, $_aStrR, $_iCountC, $_iCountR, $_iA, $_iResult
While 1
$_sStrR = _GUICtrlListView_GetItemText($_hWnd, $_iIndex -1)
$_iResult = StringCompare_($_sStrL, $_sStrR)
If $_iResult = 0 Then ExitLoop
If $_iBegin = $_iIndex Then
If $_iResult < 0 Then ExitLoop
$_iIndex = $_iEnd
ContinueLoop
ElseIf $_iIndex = $_iEnd Then
If $_iResult > 0 Then $_iIndex += 1
ExitLoop
EndIf
If $_iResult > 0 Then
$_iBegin = $_iIndex
Else
$_iEnd = $_iIndex
EndIf
$_iIndex = Int(($_iEnd +$_iBegin) /2)
WEnd
_GUICtrlListView_InsertItem($_hWnd, $_sStrL, $_iIndex -1)
EndFunc
Func StringCompare_($_sStrL, $_sStrR)
Local $_sChars = 'QWERTYUIOPLKJHGFDSAZXCVBNMmnbvcxzasdfghjklpoiuytrewqёЁА-я'
Local $_aStrL = StringRegExp($_sStrL, '(['&$_sChars&']{1,}|[0-9]{1,}|[^0-9'&$_sChars&']{1,})', 3)
If @error Then Return -1
Local $_aStrR = StringRegExp($_sStrR, '(['&$_sChars&']{1,}|[0-9]{1,}|[^0-9'&$_sChars&']{1,})', 3)
If @error Then Return 1
Local $_iCountL = UBound($_aStrL) -1
Local $_iCountR = UBound($_aStrR) -1
Local $_iCount, $_iResult, $_iTypeL, $_iTypeR
Do
$_iTypeL = StringGetType_($_aStrL[$_iCount])
$_iTypeR = StringGetType_($_aStrR[$_iCount])
Switch $_iTypeL
Case 0
If $_iTypeR > 0 Then
$_iResult = -1
Else
$_iResult = StringCompare($_aStrL[$_iCount], $_aStrR[$_iCount])
EndIf
Case 1
If $_iTypeR < 1 Then
$_iResult = 1
ElseIf $_iTypeR > 1 Then
$_iResult = -1
ElseIf Number($_aStrL[$_iCount]) > Number($_aStrR[$_iCount]) Then
$_iResult = 1
ElseIf Number($_aStrL[$_iCount]) < Number($_aStrR[$_iCount]) Then
$_iResult = -1
Else
$_iResult = 0
EndIf
Case 2
If $_iTypeR < 2 Then
$_iResult = 1
Else
$_iResult = StringCompare($_aStrL[$_iCount], $_aStrR[$_iCount])
EndIf
EndSwitch
$_iCount += 1
Until ($_iCount > $_iCountL) Or ($_iCount > $_iCountR) Or ($_iResult <> 0)
If Not $_iResult Then
If $_iCountL < $_iCountR Then Return -1
If $_iCountL > $_iCountR Then Return 1
EndIf
Return $_iResult
EndFunc
Func StringGetType_(ByRef $_sStr)
If StringIsAlpha($_sStr) Then Return 2
If StringIsDigit($_sStr) Then Return 1
Return 0
EndFunc