Что нового

[Массивы] Помогите реализовать сложную сортировку

vaf

Новичок
Сообщения
190
Репутация
2
Добрый день уважаемые форумчане. У меня проблема - не могу придумать как реализовать вот такую сортировку. Дано текстовый файл следующего содержания:
1-01-01.jpg;"126127128131132133138139140143144145148149150154155156160161162165166167168169170171176177178179182183;"
1-01-10.jpg;"127128129132133134138139140145146147149150151155156157162163164166167168171172173178179;"
1-01-13.jpg;"127128129133134135136139140141146147148154155156157160161162164165166170171172176177178179180181;"
1-01-04.jpg;"127128129133134135136139140141146147148151152153154155156157158163164165169170171172175176177181;"
1-01-05.jpg;"127128129132133134135136139140141144145146148149150151155156157160161162163164165166170171172;"
1-01-06.jpg;"128129130131132133139140141142143144150151152153154155159160161;"
1-10-10.jpg;"127128129130131132133138139140144145146147149150151156157158163164165167168169172173174;"
1-10-12.jpg;"127128129130131132138139140143144145146147149150151157158159163164165166169170171172175176177178180181;"
1-10-13.jpg;"127128129130131132138139140144145146147149150151157158159163164165166169170171172175176177178180181;"

Нужно отсортировать по координатам, состоящим из первых трех цифр. То есть сначала будут идти к примеру строки начинающиеся на
126127128129
126127128129130
126127129130
127128129130
127128129130
127128129130

В конце это примерно должно выглядеть так
1-01-01.jpg;"126127128131132133138139140143144145148149150154155156160161162165166167168169170171176177178179182183;"
1-01-13.jpg;"127128129133134135136139140141146147148154155156157160161162164165166170171172176177178179180181;"
1-01-04.jpg;"127128129133134135136139140141146147148151152153154155156157158163164165169170171172175176177181;"
1-01-05.jpg;"127128129132133134135136139140141144145146148149150151155156157160161162163164165166170171172;"
1-01-10.jpg;"127128129132133134138139140145146147149150151155156157162163164166167168171172173178179;"
т.е. как бы по максимальному соответствию.

P.S. Если это сложно или невозможно буду рад примеру сортирующему хотя бы по первым 20 ти 3х значным значениям. Возможно нужно сначала отсортировать по первой цифре, потом по второй, третьей и т.д.
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
vaf
Как вариант:

Код:
; НАЧАЛО

 #Include <Array.au3>

 $PATH='2.txt'

 Dim $A[0][2]

 $COUNTER=0

 $FILE=FileOpen($PATH,0)
 While True
  $LINE=FileReadLine($FILE)
  If @Error=-1 Then ExitLoop
  ReDim $A[$COUNTER+1][2]
  $A[$COUNTER][1]=$LINE
  $A[$COUNTER][0]=StringTrimLeft($LINE,12)
  $COUNTER+=1
 WEnd
 FileClose($FILE)

 _ArraySort($A)

 $FILE=FileOpen($PATH,2)
 For $COUNTER=0 To Ubound($A)-1
  FileWriteLine($FILE,$A[$COUNTER][1])
 Next
 FileClose($FILE)

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

vaf

Новичок
Сообщения
190
Репутация
2
snoitaleR сказал(а):
vaf
Как вариант:

Код:
; НАЧАЛО

 #Include <Array.au3>

 $PATH='2.txt'

 Dim $A[0][2]

 $COUNTER=0

 $FILE=FileOpen($PATH,0)
 While True
  $LINE=FileReadLine($FILE)
  If @Error=-1 Then ExitLoop
  ReDim $A[$COUNTER+1][2]
  $A[$COUNTER][1]=$LINE
  $A[$COUNTER][0]=StringTrimLeft($LINE,12)
  $COUNTER+=1
 WEnd
 FileClose($FILE)

 _ArraySort($A)

 $FILE=FileOpen($PATH,2)
 For $COUNTER=0 To Ubound($A)-1
  FileWriteLine($FILE,$A[$COUNTER][1])
 Next
 FileClose($FILE)

; КОНЕЦ

странно, ругается на строку Dim $A[0][2]
Array variable subscript badly formatted.:
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
vaf,
Как вариант, сортировка по первым 15-ти цифрам.
Код:
#include <Array.au3>

Local $aSort[1], $aRead, $sFile = @ScriptDir & '\txt.txt', $sTxt, $hFile

$aRead = StringSplit(StringRegExpReplace(StringStripCR(FileRead($sFile)), '\s*$', ''), @LF)
ReDim $aSort[$aRead[0] + 1][2]
For $i = 1 To $aRead[0]
	$sTxt = StringRegExpReplace($aRead[$i], '.*[''"](\d{15}).*', '$1')
	If @extended = 1 Then
		$aSort[0][0] += 1
		$aSort[$aSort[0][0]][0] = Number($sTxt)
		$aSort[$aSort[0][0]][1] = $aRead[$i]
	EndIf
Next
If Not $aSort[0][0] Then Exit 13
$sTxt = ''
If $aSort[0][0] <> $aRead[0] Then ReDim $aSort[$aSort[0][0] + 1][2]
$aRead = 0
_ArraySort($aSort, 0, 1)
For $i = 1 To $aSort[0][0]
	$sTxt &= $aSort[$i][1] & @CRLF
Next
$hFile = FileOpen($sFile & '_new.txt', 2)
FileWrite($hFile, StringTrimRight($sTxt, 2))

vaf [?]
ругается на строку Dim $A[0][2]
Поменяйте на Dim $A[1][2].
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
vaf
Прошу прощение за недоразумение... Я обычно пользуюсь AUTOIT.3.3.8.1, но последнее время решил протестировать бета-версию AUTOIT.3.3.11.2...
В ней [ 0 ] - элемент считается легитимным...
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
[Массивы] Помогите реализовать сортировку

Помогите реализовать сотрировку
Нужно отсортировать по максимальному вхождению цифр. поясню. К примеру - есть текстовый файл следующего содержания:

Я буду выделять жирным совпадения
4.jpg;"126127128130131132133134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
5.jpg;"126127128130131132133135136137138141142143144147148149152153154158159160161162163164170171172174175176;"
6.jpg;"126127128130131132133135136137138141142143144148149150151152153159160161162163164165166;"
7.jpg;"126127128130131132133135136137142143144149150151152153154160161162164165166;"
8.jpg;"126127128130131132133136137138144145146149150151152;"
9.jpg;"126127128130131132134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
10.jpg;"126127128130131132135136137142143144147148149154155156159160161162163164169170171172176177178181182183187188189190;"
11.jpg;"126127128130131132135136137142143144149150151152153154160161162164165166;"
12.jpg;"126127128130131132135136137142143144149150151153154155156159160161167168169174175176181182183185186187190191192197198199201202203206207208212213214215;"
13.jpg;"126127128130131132135136137142143144150151153154155156159160161167168169174175176181182183185186187190191192197198199201202203206207208212213214215;"
14.jpg;"126127128131132133134135136137142143144148149150151;"
15.jpg;"126127128131132133134135136137142143144148149150151154155156157158159160166167168172173174175176177178179180;"
16.jpg;"126127128131132133134135136142143144148149150151154155156157158159160166167168172173174175176177178179180;"
17.jpg;"126127128131132133134135136144145146147148149150153154155156157158163164165166170171172177178179181182183185186187;"
18.jpg;"126127128131132133134137138139140142143144146147148151152153154155156157162163164169170171173174175176180181182188189190191195196197198199200201202203;"

Тут наибольшее совпадение в 4.jpg и 9.jpg, т.к. комбинации
126127128130131132 и
135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196
есть и в 4.jpg и в 9.jpg

В 7.jpg и 11.jpg так же имеются одинаковые комбинации - это
126127128130131132 и
135136137142143144149150151152153154160161162164165166

В 12.jpg и 13.jpg одинаковые комбинации
126127128130131132135136137142143144 и
150151153154155156159160161167168169174175176181182183185186187190191192197198199201202203206207208212213214215

В 15.jpg и 16.jpg одинаковые

126127128131132133134135136 и
142143144148149150151154155156157158159160166167168172173174175176177178179180

Результирующий файл примерно будет таким
4.jpg;"126127128130131132133134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
9.jpg;"126127128130131132134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
7.jpg;"126127128130131132133135136137142143144149150151152153154160161162164165166;"
11.jpg;"126127128130131132135136137142143144149150151152153154160161162164165166;"
12.jpg;"126127128130131132135136137142143144149150151153154155156159160161167168169174175176181182183185186187190191192197198199201202203206207208212213214215;"
13.jpg;"126127128130131132135136137142143144150151153154155156159160161167168169174175176181182183185186187190191192197198199201202203206207208212213214215;"
15.jpg;"126127128131132133134135136137142143144148149150151154155156157158159160166167168172173174175176177178179180;"
16.jpg;"126127128131132133134135136142143144148149150151154155156157158159160166167168172173174175176177178179180;"

.... и дальше все остальные ....

Есть какие либо мысли, как это возможно реализовать ?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
vaf,
Я объединил Ваши темы.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Постановка последней задачи вообще никуда не годится.
Потому что критерий сортировки задан для ПАР элементов. Но порядок формирования этих пар нигде не определён.
Например. Вы нашли что есть совпадение в 4.jpg и в 9.jpg.
А потом Вы находите ещё большее совпадение в 9.jpg и в 11.jpg.
Что делать с парой 4.jpg и в 9.jpg? Расформировывать? Что делать с 4.jpg? Включать повторно в обработку?
Если у Вас совпадение не в паре, а в бОльшем количестве - 2.jpg, 3.jpg и 7.jpg имеют одинаковое совпадение.
Что делать с этой тройкой?
И т.д.

vaf
Вы это файл мусолите с марта месяца. Вы определитесь, наконец, что с ним нужно сделать.
Разработайте алгоритм, а не вбрасываёте взятые с потолка задачи.




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

А сама функция сравнения строк будет выглядеть вот так
Код:
#Include <Array.au3>

$S4 = "126127128130131132133134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196"
$S9 = "126127128130131132134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196"

$aR = _drink($S4,$S9)

_ArrayDisplay($aR)

Func _drink($str1,$str2)
	$aStr1 = StringToASCIIArray($str1)
	$aStr2 = StringToASCIIArray($str2)
	Local $N1 = UBound($aStr1), $N2 = UBound($aStr2)
	Local $Matrix[$N2][$N1]
	Local $maxLen = 0, $maxPos1, $maxPos2

	For $i=0 To $N1-1
		If $aStr1[$i] = $aStr2[0] Then
			$Matrix[0][$i] = 1
		Else
			$Matrix[0][$i] = 0
		EndIf
	Next

	For $j=0 To $N2-1
		If $aStr2[$j] = $aStr1[0] Then
			$Matrix[$j][0] = 1
		Else
			$Matrix[$j][0] = 0
		EndIf
	Next

	For $i=1 To $N1-1
		For $j=1 To $N2-1
			If $aStr1[$i]=$aStr2[$j] Then
				$Matrix[$j][$i] = $Matrix[$j-1][$i-1] + 1
				If $Matrix[$j][$i] > $maxLen Then
					$maxLen = $Matrix[$j][$i]
					$maxPos1 = $i
					$maxPos2 = $j
				EndIf
			Else
				$Matrix[$j][$i] = 0
			EndIf
		Next
	Next

	Local $Res[3] = [$maxLen, $maxPos1-$maxLen+1, $maxPos2-$maxLen+1]
	; [длинна совпадения, начало совпадения в первой строке, начало совпадения во второй строке]

	Return $Res
EndFunc

Да, да, vaf
в Вашем примере в 4.jpg и в 9.jpg перед выделенной подстрокой "134" тоже совпадают.
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
Лучше скажу зачем мне это нужно, сразу будет понятно.
вот эти числа, это координаты, они трехзначные, 126,127,128 и т.д. но в некоторых попадаются как бы нежелательные элементы, которые мешают сортировке.

Допустим есть строки :

4.jpg;"126127128130131132133134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
5.jpg;"126127128130131132133135136137138141142143144147148149152153154158159160161162163164170171172174175176;"
6.jpg;"126127128130131132133135136137138141142143144148149150151152153159160161162163164165166;"
9.jpg;"126127128130131132134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"

комбинация "126127128130131132" есть в каждой, далее идет 133 это встречается только в 4.jpg, 5.jpg, 6.jpg и далее 134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196
есть в 4.jpg и в 9.jpg. Следовательно это две строки имеют всех больше совпадений, их и ставим выше.
т.к. координаты трехзначные, может просто сначала подсчитать во всем списке количество вхождений первой координаты, т.е. 126, потом 127 и т.д., потом все эти количества вхождений сложить и отсортировать по этому значению ?
только ума не приложу как это сделать ?
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
То есть Вы считает что строки "126127128130131132" и "132131130128127126" совпадают?
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
C2H5OH сказал(а):
То есть Вы считает что строки "126127128130131132" и "132131130128127126" совпадают?
Да я вроде так и не говорил. Просто задача такая, сразу и не поймешь как это реализовать
Посмотрите повыше, я более понятно сформулировал что нужно :smile:
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Да я вроде так и не говорил

Вы именно так и сказали
координаты трехзначные, может просто сначала подсчитать во всем списке количество вхождений первой координаты, т.е. 126, потом 127 и т.д., потом все эти количества вхождений сложить

При такой системе подсчета строки "126127128130131132" и "132131130128127126" полностью совпадают.
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
При такой системе подсчета строки "126127128130131132" и "132131130128127126" полностью совпадают.
т.к. это координаты, меня в принципе это устроит. Да, я думаю такая сортировка мне подойдет, т.е. сначала подсчитать все вхождения 126, потом 127, 128 и т.д. сложить количество вхождений по каждой строке и отсортировать по получившимся значениям.
Поможете ?
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Мне не понятен принцип сортировки пар. Смотрите вопросы выше.
Я понимаю когда нужно отсортировать по совпадению с шаблоном или по какому-то внятному критерию. Но как выбирать пары?...
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
C2H5OH сказал(а):
Мне не понятен принцип сортировки пар. Смотрите вопросы выше.
Я понимаю когда нужно отсортировать по совпадению с шаблоном или по какому-то внятному критерию. Но как выбирать пары?...
Пары были для примера, чтобы показать что именно совпадает. Искать пары это тупиковый метод, т.к. сложный и вообще не реализуемый.

Так как у меня координаты всегда идут в порядке возрастания 126, 127, 128 и т.д.
проще просто посчитать для каждой строки все вхождения 126, потом 127, 128 и т.д. сложить количество вхождений по каждой строке и отсортировать по получившимся значениям. Вот это будет самое простой и действенный метод.
Единственное, не хватает виртуозности владения AutoIt чтобы это реализовать :smile:

P.S. Хорошая мысля приходит опосля, метод поиска одинаковых цепочек слишком муторно и долго, проще как написал выше. результат будет таким же.

P.P.S. А вообще если ответить на ваш вопрос откуда брать вот эти цепочки, то задумывал чтобы программа сама их искала. Это самые длинные и самые часто повторяющиеся цепочки во всем списке.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
Код:
#include <array.au3>
$file = FileReadToArray('file.txt') ;_FileReadToArray('file.txt') ; Если старая версия
$total_lines = UBound($file)
Local $out[$total_lines][2]
Local $min = 0
Local $max = 0
For $line In $file
	$min = StringRegExp($line, '(?<=")(\d{3})', 1)
	If Not IsArray($min) Then Exit MsgBox(0, '', 'Формат не правильный. Строка: ' & $line)
	$min = $min[0]
	$max = StringRegExp($line, '(\d{3})(?=;)', 1)
	If Not IsArray($max) Then Exit MsgBox(0, '', 'Формат не правильный. Строка: ' & $line)
	$max = $max[0]
Next
$line = 0
For $i = $min To $max
	For $line = 0 To $total_lines - 1
		$digits = StringRegExp($file[$line], '(?<=")\d+', 3)
		If Not IsArray($digits) Then Exit MsgBox(0, '', 'Формат не правильный. Строка: ' & $line)
		$out[$line][1] = $line


		If StringInStr($digits[0], $i) Then
			$out[$line][0] += 1

		EndIf
	Next
Next
_ArraySort($out, 1)
Local $hFileOut = FileOpen('out.txt', 2)
For $i = 0 To UBound($out) - 1
	$orig_index = $out[$i][1]
	$orig_line = $file[$orig_index]
	FileWriteLine($hFileOut, $orig_line)
Next
FileClose($hFileOut)



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

Черт, не совпадает с вашим результатом :smile:
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
:mad: :evil: :Censored:
самые длинные и самые часто повторяющиеся цепочки во всем списке

Цепочка "126127128" есть в каждой строке - она самая часто повторяющаяся.
Цеопчка "....." - самая длиннная, но она встречается только в двух файлах (4 и 9).

Сформулируйте критерий поиска. Что Вам нужно найти?
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
Сформулируйте критерий поиска. Что Вам нужно найти?
Скажем так, что нужно отсортировать (сгруппировать) список по максимально длинным, повторяющимся значениям, просто эти значения могут быть не только с самого начала, но и в середине.

к примеру дано :

4.jpg;"126127128130131132133134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
5.jpg;"126127128130131132133135136137138141142143144147148149152153154158159160161162163164170171172174175176;"
7.jpg;"126127128130131132133135136137142143144149150151152153154160161162164165166;"
9.jpg;"126127128130131132134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196;"
11.jpg;"126127128130131132135136137142143144149150151152153154160161162164165166;"

в 4.jpg и 9.jpg есть одинаковые куски - это 126127128130131132 и 134135136137139140141146147148153154155156157158159160163164165166170171172175176177182183184187188189190194195196

В 7.jpg и 11.jpg так же имеются одинаковые куски, это
126127128130131132 и
135136137142143144149150151152153154160161162164165166

соответственно пусть список будет отсортирован (сгруппирован) по этим совпадениям, т.е. сначала пойдет 4.jpg, потом 9.jpg, потом 7.jpg и 11.jpg
эти одинаковые куски программа должна выявлять сама. как это сделать я ума не приложу.

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

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Вчера я просил чтобы помогли сделать сортировку, помогли, но она не учитывает вот этих нюансов.

Ну, это ж не к программисту вопрос. То что Вы просили вчера, Вам предоставили.

Вы забудьте пока про AutoIt, про ЯП вообще.
Возьмите листочек, карандаш, нарисуйте блок-схему. Разработайте АЛГОРИТМ. Что нужно сделать.
Потому что пока вы не сможете объяснить чего хотите добиться, помочь Вам вряд ли смогут.

Забудьте даже про этот файл. Нарисуйте цепочки точек разного цвета (это ж в файле координаты точек, правильно?). А потом попробуйте понять и сформулировать какие точки нужно оставить, а какие выбросить, чтобы получить нужный вам результат.
 
Автор
V

vaf

Новичок
Сообщения
190
Репутация
2
Поломаю мозг, как это реализовать. Может быть отсутствующие координаты заменить просто нулевыми значениями и потом сортировать по каждому столбцу в массиве или можно каждой присутствующей координате присвоить "1", отсутствующей "0", например.
126127128129130 будет выглядеть как 11111
126127130 будет выглядеть как 11001

получится таблица вида

5.jpg;" 11101111010111
7.jpg;" 1110100110110
9.jpg;" 1100111001011
11.jpg;"1010111001010
4.jpg;" 10101101101101

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