Что нового

Сложная сортировка массива (по дате и номеру)

Suppir

Продвинутый
Сообщения
967
Репутация
62
Есть следующий массив:
Постановление главы администрации Краснодарского края от 13.09.2010 N 871
Постановление главы администрации Краснодарского края от 25.04.2006 N 285
Постановление главы администрации Краснодарского края от 22.02.2005 N 149
Постановление главы администрации Краснодарского края от 17.07.2006 N 621
Постановление главы администрации Краснодарского края от 06.02.2009 N 79
Постановление главы администрации Краснодарского края от 03.09.2007 N 796
Постановление главы администрации Краснодарского края от 08.08.2007 N 725
Постановление главы администрации Краснодарского края от 19.12.2008 N 1217
Постановление главы администрации Краснодарского края от 24.10.2006 N 923
...

Необходимо отсортировать следующим образом: вверху должны идти документы с самой свежей датой, если у документов одинаковая дата, то вверху должен идти документ с максимальным номером.


Добавлено:
Сообщение автоматически объединено:

Причем, как вы понимаете, под свежей датой имеется
1) самый большой год
2) потом самый большой месяц
3) потом самый большой день

т.е. в строке (13).(09).(2010) N (1313) необходимо сначала сравнивать 3-й элемент, потом 2-й, потом 1-й, а потом 4-й.


Добавлено:
Сообщение автоматически объединено:

OffTopic:
Офф. На Perl это делается примерно так:

@array=sort{($a=~ /(\d+) N/)[0] <=> ($b=~ /(\d+) N/)[0]
||
($a=~ /\.(\d+)\./)[0] <=> ($b=~ /\.(\d+)\./)[0]
||
($a=~ / от (\d+)/)[0] <=> ($b=~ /от (\d+)/)[0]
||
($a=~ / N (\d+)/)[0] <=> ($b=~ / N (\d+)/)[0]}@unsorted;
 

dwerf

Использует ArchLinux
Сообщения
478
Репутация
219
Сваял нечто похожее для соротировки процессов в моей программе.
Как то так (Ctrl+NumPlus разворачивает ListView):
Код:
#include <array.au3>

Dim $aArray[10]
$aArray[0] = 9
$aArray[1] = 'Постановление главы администрации Краснодарского края от 13.09.2010 N 871'
$aArray[2] = 'Постановление главы администрации Краснодарского края от 25.04.2006 N 285'
$aArray[3] = 'Постановление главы администрации Краснодарского края от 22.02.2005 N 149'
$aArray[4] = 'Постановление главы администрации Краснодарского края от 17.07.2006 N 621'
$aArray[5] = 'Постановление главы администрации Краснодарского края от 19.12.2008 N 12170'
$aArray[6] = 'Постановление главы администрации Краснодарского края от 03.09.2007 N 796'
$aArray[7] = 'Постановление главы администрации Краснодарского края от 08.08.2007 N 725'
$aArray[8] = 'Постановление главы администрации Краснодарского края от 19.12.2008 N 1217'
$aArray[9] = 'Постановление главы администрации Краснодарского края от 19.12.2008 N 127'
_ArrayDisplay($aArray)

Sort($aArray, ' ', -1)
Sort($aArray, ' ', -3)
Sort($aArray, '.', -2)
Sort($aArray, '.', -1)
_ArrayDisplay($aArray)


Func Sort(ByRef $aArray, $sSubString, $iOccurence)
	Local $min, $var, $id
	For $i = 1 To $aArray[0] Step +1
		$min = -1
		For $i2 = $i To $aArray[0] Step +1
			If $aArray[$i2] = '' Then ContinueLoop
			$var = Int(StringTrimLeft($aArray[$i2], StringInStr($aArray[$i2], $sSubString, 0, $iOccurence)))
			If $var > $min Then
				$min = $var
				$id = $i2
			EndIf
		Next
		$var = $aArray[$id]
		For $i2 = $id-1 To $i Step -1
			$aArray[$i2+1] = $aArray[$i2]
		Next
		$aArray[$i] = $var
	Next
EndFunc
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Suppir
Мой вариант:

Код:
; НАЧАЛО

; Библиотеки

 #include <array.au3>

 Dim $ARRAY[9]=["Постановление главы администрации Краснодарского края от 13.09.2010 N 871", _
                "Постановление главы администрации Краснодарского края от 25.04.2006 N 285", _
                "Постановление главы администрации Краснодарского края от 22.02.2005 N 149", _
                "Постановление главы администрации Краснодарского края от 17.07.2006 N 621", _
                "Постановление главы администрации Краснодарского края от 17.07.2006 N 700", _
                "Постановление главы администрации Краснодарского края от 03.09.2007 N 796", _
                "Постановление главы администрации Краснодарского края от 08.08.2007 N 725", _
                "Постановление главы администрации Краснодарского края от 19.12.2008 N 1217", _
                "Постановление главы администрации Краснодарского края от 24.10.2006 N 923"]

 Dim $ACODE[UBound($ARRAY)][2]

 For $iARRAY=0 To UBound($ARRAY)-1

  $ACODE[$iARRAY][0]=StringRegExpReplace($ARRAY[$iARRAY],"(.*)(\d\d)(\.)(\d\d)(\.)(\d\d\d\d)(.*)","\6\5\4\3\2")&"."&StringFormat("%05d",StringRegExpReplace($ARRAY[$iARRAY],"(.*)(N )(\d+)","\3"))
  $ACODE[$iARRAY][1]=$ARRAY[$iARRAY]

 Next

 _ArraySort($ACODE,1)

 For $iARRAY=0 To UBound($ARRAY)-1

  $ARRAY[$iARRAY]=$ACODE[$iARRAY][1]

 Next 

 _ArrayDisplay($ARRAY)

; КОНЕЦ



Добавлено:
Сообщение автоматически объединено:

Suppir
Немного видоизменил и оптимизировал скрипт:

Код:
; НАЧАЛО

; Библиотеки

 #include <array.au3>

; Объявление массива

 Dim $A[9][2]

; Заполнение нулевого размера

 $A[0][0]="Постановление главы администрации Краснодарского края от 13.09.2010 N 871"
 $A[1][0]="Постановление главы администрации Краснодарского края от 25.04.2006 N 285"
 $A[2][0]="Постановление главы администрации Краснодарского края от 22.02.2005 N 149"
 $A[3][0]="Постановление главы администрации Краснодарского края от 17.07.2006 N 621"
 $A[4][0]="Постановление главы администрации Краснодарского края от 17.07.2006 N 700"
 $A[5][0]="Постановление главы администрации Краснодарского края от 03.09.2007 N 796"
 $A[6][0]="Постановление главы администрации Краснодарского края от 08.08.2007 N 725"
 $A[7][0]="Постановление главы администрации Краснодарского края от 19.12.2008 N 1217"
 $A[8][0]="Постановление главы администрации Краснодарского края от 24.10.2006 N 923"

; Заполнение первого размера

 For $iA=0 To UBound($A)-1

  $A[$iA][1]=StringRegExpReplace($A[$iA][0],"(.*)(\d\d)(\.)(\d\d)(\.)(\d\d\d\d)(.*)","\6\4\2")&StringFormat("%05d",StringRegExpReplace($A[$iA][0],"(.*)(N )(\d+)","\3"))

 Next

; Сортировка по первому размеру

 _ArraySort($A,1,0,0,1)

; Отображение отсортированного массива

 _ArrayDisplay($A)

; КОНЕЦ
 
Автор
S

Suppir

Продвинутый
Сообщения
967
Репутация
62
snoitaleR
вроде работает, только я не совсем понимаю, каким образом :-[ Не мог бы ты немножко пояснить алгоритм...
 

snoitaleR

AutoIT Гуру
Сообщения
854
Репутация
223
Suppir
Есть предыстория... Я очень долго искал способ создания уникальных имен документов и всевозможных пометок, которые бы ни в коем случае не повторялись... И я нашел способ: YYYY-MM-DD-hh-mm-ss... Для событий из жизни людей практически невозможно получить два события с одинаковым YYYY-MM-DD-hh-mm-ss... У этого "псевдослучайного" кода есть важная особенность - правильная сортировка по времени...
В решении твоей задачи я просто заменил часы-минуты-секунды на номер документа и получил код: YYYYMMDDnnnnn...
Функция _ArraySort() позволяет сортировать 2-мерный массив по любому измерению... А в качество измерения для сортировки я выбрал измерение с кодами YYYYMMDDnnnnn...
Если бы даты нужно было упорядочить по убыванию, а номера документов по возрастанию, то данный алгоритм было бы использовать нельзя, так как я объединил даты и номера в одно измерение... :smile:
 
Верх