Что нового

[Данные, строки] как быстро удалить повторяющиеся строки

andreitrane

Новичок
Сообщения
141
Репутация
3
помогите ускорить работу скрипта для удаления дублирующихся строк
просто мой скрипт просматривает 1млн строк примерно за 4 мин с лишним, а есть ДупКилл, который этот же 1млн строк смотрит за 1 сек...
Код:
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>
#Region ### START Koda GUI section ### Form=
$tdkForm = GUICreate("TextDuplikatKiller maniakk mod", 457, 258, 180, 120)
$textfromfilebtn = GUICtrlCreateButton("Из файла", 8, 8, 73, 25)
$textin = GUICtrlCreateEdit("", 8, 40, 217, 209, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
$textout = GUICtrlCreateEdit("", 232, 40, 217, 209, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
$tdkstart = GUICtrlCreateButton("Начать", 88, 8, 73, 25)
$tdkProgress = GUICtrlCreateProgress(168, 8, 281, 25)
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $textfromfilebtn
			_textfromfile()
		Case $tdkstart
			_tdkstart()
			if $dupnum > 0 Then
		MsgBox(0, "", "Удалено "& $dupnum &" повторяющихся строк"&@CRLF&"сохранено в "&$text&"_no dups.txt")
		ElseIf $dupnum = 0 Then
		MsgBox(0, "", "Нет повторяющихся строк")
		EndIf

	EndSwitch
WEnd

Func _textfromfile()

			Global $text = FileOpenDialog("Указать файл", @WorkingDir & "", "Любой (*.txt)", 1 + 4 )
        Global $Readch = FileRead($text)
		if $Readch Then
        GUICtrlSetData($textin,$Readch)
		EndIf
		EndFunc

Func _tdkstart()
	Global $nodup = ""
	Global $dupnum = 0
		$textstr = StringSplit(StringStripCR(GUICtrlRead($textin)), @LF)
		For $itdk = 1 to $textstr[0]
			GUICtrlSetData($tdkProgress, Round($itdk*(100/$textstr[0])))
			If $textstr[$itdk] = "" then ContinueLoop
			if not StringInStr($nodup, $textstr[$itdk]&@CRLF) Then
				$nodup &= $textstr[$itdk]&@CRLF
		GUICtrlSetData($textout, $textstr[$itdk]&@CRLF,@CRLF)
			Else
				$dupnum += 1
			EndIf
		Next
		FileWrite($text&"_no dups.txt", $nodup)


	EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [Данные, строки] TextDupKill ускорить работу

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


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

1. судя по скрипту, ты добавляешь свои миллионы строк в Edit? это так? если да, то зачем? знаешь ли ты про ограничение размера текста в поле ввода?
2. и еще, такого флага открытия файла как 1+4 нет, как мне известно. если ты читаешь строки из одного файла и ставишь в другой, то достаточно просто флага 0 для чтения.
3. твой скрипт не ищет дубликаты строк, а просто повторения фрагментов. другими словами, если некая строка является частью другой строки, то она не войдет в конечный файл, что неправильно.
 
Автор
A

andreitrane

Новичок
Сообщения
141
Репутация
3
Re: [Данные, строки] TextDupKill ускорить работу

Kaster [?]
1. судя по скрипту, ты добавляешь свои миллионы строк в Edit? это так? если да, то зачем? знаешь ли ты про ограничение размера текста в поле ввода?
про ограничение я знаю, это я просто для вида сделал, а так все читает из файла, а не из edit
Kaster [?]
2. и еще, такого флага открытия файла как 1+4 нет, как мне известно. если ты читаешь строки из одного файла и ставишь в другой, то достаточно просто флага 0 для чтения.

ну я просто много примеров видел, вот и пишу такKaster [?]
3. твой скрипт не ищет дубликаты строк, а просто повторения фрагментов. другими словами, если некая строка является частью другой строки, то она не войдет в конечный файл, что неправильно
а как тогда сделать чтобы искал дубликаты?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [Данные, строки] TextDupKill ускорить работу

Предупреждение За нарушение правил форума (пункт Б.5):
Имя темы должно нести смысловую нагрузку (отражать суть вопроса/проблемы)
Правильно сформулированное название темы привлекает больше внимания, и шансы получить конкретный ответ увеличиваются.


Как правильно называть темы

"[Данные, строки] TextDupKill ускорить работу" - это неприемлемое название темы, переименуйте тему иначе она будет закрыта, а вам возможно будет выдан бан на несколько дней.

С уважением, Модератор раздела.








andreitrane [?]
а так все читает из файла, а не из edit
тогда возможно весь твой скрипт это так для вида, а готовый и работающий у тебя есть.
я к тому, что выкладывать нужно репрезентативный код. иначе ты обрекаешь людей на лишний труд. а это никому не надо.
ну я просто много примеров видел, вот и пишу так
примеры примерами, а справку никто не отменял. она – эталон, а все эти примеры, это лишь варианты ее использования.
а как тогда сделать чтобы искал дубликаты?
ну например ставить каждой строке в соответствие некий слепок, который уникален для нее. например MD5 или CRC32. читать файл построчно, а не весь, снять слепок, занести этот слепок в массив. потом перейти к след. строке, и если его слепок уже есть в массиве – значит это повтор. и так далее. но для больших файлов, это конечно же будет довольно медленно. быстродействие этого метода растет примерно как N^2, где N - кол-во строк. то есть для миллиона строк это будет 10^12 операций. при самом худшем раскладе. возможно есть оптимизированные методы, но я не в курсе, мне не особо надо было обрабатывать именно большие файлы. но в любом случае, твой dupkiller или как его там, его способность обработать миллион строк (что в среднем несколько десятков мегабайт) за 1 сек выглядит крайней неправдоподобной. можно поверить что он работает быстрее по сравнению с AutoIt, если написан на языке более низкого уровня, но 1 сек, это что-то за гранью.
 
Автор
A

andreitrane

Новичок
Сообщения
141
Репутация
3
Re: [Данные, строки] TextDupKill ускорить работу

Kaster [?]
1 сек, это что-то за гранью.
это написано не на autoit, написал vilkaa (наверно знаете), а он пишет либо на С# либо на javascript
я загрузил туда свой файл и он за 1 сек проверил...


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

кстати вот пример от Creator, я писал исходя из него
Код:
$sFileName = "Test.txt"
$sFilePath = @ScriptDir & "\"
$sFile = $sFilePath & $sFileName

$iRet = _FileDeleteDuplicateLines($sFile, 0)
$iExtended = @extended

If $iRet = 1 And $iExtended > 0 Then
    MsgBox(64, "Results", StringFormat("В файле <%s> удалено дублирующихся строк: %i", $sFileName, $iExtended))
ElseIf $iExtended = 0 Then
    MsgBox(64, "Results", StringFormat("В файле <%s> нет дублирующихся строк.", $sFileName))
ElseIf @error = 1 Then
    MsgBox(48, "Ошибка", StringFormat("Файл <%s> не найден.", $sFileName))
ElseIf @error = 2 Then
    MsgBox(48, "Ошибка", StringFormat("Ошибка при попытке записи в Файл <%s>.", $sFileName))
EndIf

Func _FileDeleteDuplicateLines($sFile, $iCaseSense=0)
    If Not FileExists($sFile) Then Return SetError(1)
    Local $sFRead = FileRead($sFile)
    Local $aFSplit = StringSplit(StringStripCR($sFRead), @LF)
    Local $sFileContent = "", $iExtended = 0, $sLastChars = StringRight($sFRead, 2)
    
    ;Проходим весь массив, и проверяем каждую строку
    For $i = 1 To $aFSplit[0]
        If $aFSplit[$i] = "" Then ContinueLoop
        
        ;Тут делаем проверку в переменной, в которую скапливаются строки (не дублирующиеся)
        If Not StringInStr($sFileContent, $aFSplit[$i] & @CRLF, $iCaseSense) Then
            $sFileContent &= $aFSplit[$i] & @CRLF
        Else
            $iExtended += 1
        EndIf
    Next
    
    If $sLastChars <> @CRLF Then $sFileContent = StringTrimRight($sFileContent, 2)
    
    ;Пишем в файл уже без дублей
    Local $hFOpen = FileOpen($sFile, 2)
    If $hFOpen = -1 Then Return SetError(2)
    
    FileWrite($hFOpen, $sFileContent)
    FileClose($hFOpen)
    
    Return SetExtended($iExtended, 1)
EndFunc
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [Данные, строки] Text Duplicate Killer ускорить работу

andreitrane [?]
написал vilkaa (наверно знаете)
нет, не знаю.
я загрузил туда свой файл и он за 1 сек проверил...
именно с 1 млн строк?
[?]
кстати вот пример от Creator, я писал исходя из него
страдает той же болезнью. попробуй проверить.
пусть у тебя в файле будут строки
Код:
111
11
он удалит вторую строку как дубль, потому что попадет под StringInStr


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

пользуйся объединением сообщений.


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

и еще, ты не понял, про название темы. обзови ее так, чтобы название отражало суть проблемы. ты же не хочешь ускорить работу программы vilkaa который и так быстрее скорости света?


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

andreitrane
ок, погуглил я этот Dupkiller. создал для этого специально большой файл в 1млн строк. содержание примерно такое
Код:
1
11
111
...
и так до 10 единиц. потом по новой. как результат – dublicate killer все еще работает. причем процент на 0. хотя прошло минуты 3, так что чудес не бывает.
тебе совет на будущее, если ты хочешь получить помощь, не нужно приукрашивать. говори как есть. если делал тесты – точные результаты, условия проверки, детали и прочее...

UPD:
не дождался окончания работы программы. скорость обработки 100 строк - 0.2 секунды. что довольно медленно. это конечной крайне неудачный вариант текста, слишком много повторений. исключительно для демонстрации
 
Автор
A

andreitrane

Новичок
Сообщения
141
Репутация
3
Re: [Данные, строки] Text Duplicate Killer ускорить работу

Kaster [?]
ты же не хочешь ускорить работу программы vilkaa который и так быстрее скорости света
я не хочу ускорять работу скрипта vilkaa, я хочу ускорить свой, потому что он у меня проверяет за 4 мин 1 млн строк, а у него, без преувеличений, за 1 сек
он удалит вторую строку как дубль, потому что попадет под StringInStr
можете привести небольшой пример как сделать?
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Re: [Данные, строки] Text Duplicate Killer ускорить работу

andreitrane
Эту проблему уже обсуждали на форуме.

Создаем файл в 1000000 строк:
Код:
#include <String.au3>
$sText = ''
For $j = 1 To 100000
	For $i = 1 To 10
		$sText &= _StringRepeat('1', $i) & @CRLF
	Next
Next
$hFile = FileOpen(@ScriptDir & '\test.txt', 2)
FileWrite($hFile, StringTrimRight($sText, 2))
FileClose($hFile)

Ищем уникальные строки в нем:
Код:
$sText = ''
$iStart = TimerInit()
$aList = StringSplit(StringStripCR(FileRead(@ScriptDir & '\test.txt')), @LF)
ConsoleWrite($aList[0] & @CR)
For $i = 1 To $aList[0]
	Assign($aList[$i] & '/\', Eval($aList[$i] & '/\') + 1)
	If Eval($aList[$i] & '/\') = 1 Then
		$sText &= $aList[$i] & @CRLF
	EndIf
Next
$hFile = FileOpen(@ScriptDir & '\test_1.txt', 2)
FileWrite($hFile, StringTrimRight($sText, 2))
FileClose($hFile)
$sTime = StringFormat('%.2f sec', TimerDiff($iStart) / 1000)
MsgBox(64, 'Info', $sTime)

У меня это занимает чуть больше 7 секунд. Дайте ссылку на программу Text Duplicate Killer, которая делает это за 1 секунду.
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Re: [Данные, строки] Text Duplicate Killer ускорить работу

andreitrane [?]
я не хочу ускорять работу скрипта vilkaa
однако именно это у тебя указано в теме. в третий, и последний раз предлагаю переименовать тему в соответствии с сутью проблемы
а у него, без преувеличений, за 1 сек
выше я написал, что тот файл с 1 млн строками что я создал искусственно, эта программа проверяла еще дольше. куда дольше чем 4 мин. и я даже не дождался окончания. поэтому и странно. покажи как ты создал свой файл с млн строками. но в любом случае, как у него не получится. потому что он по всей видимости использует хеш, тип данных который в AutoIt не поддерживается. все эти поэлементные проверки массивов очень ресурсоемкие функции.
можете привести небольшой пример как сделать?
сделать что?


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

madmasles
красота :smile: вот и замена хешу, Assign не даст создать дубликат :smile:
у меня миллион строк отработали за 1.5 сек!
 
Автор
A

andreitrane

Новичок
Сообщения
141
Репутация
3
Re: [Данные, строки] Text Duplicate Killer ускорить работу

Kaster [?]
однако именно это у тебя указано в теме. в третий, и последний раз предлагаю переименовать тему в соответствии с сутью проблемы
тему переименовал
но опять же перечитайте мой первый пост
где там сказано что я хочу ускорить прогу vilkaa? я прошу чтобы мне помогли ускорить свой скрипт
madmasles
спасибо, щас поюзаю
[?]
Дайте ссылку на программу Text Duplicate Killer, которая делает это за 1 секунду.

вот http://zalil.ru/31003684
там конечно надо зарегистрироваться, но ничего страшного
сверху выбрать вкладку "модули" (там такие шестиренки) и в самом низу запустить Duplicate Ciller
 

AZJIO

Меценат
Меценат
Сообщения
2,892
Репутация
1,196
andreitrane
Посмотри тему
Попробуй ещё функцию _ArrayUnique - удаление повторов.
 
Верх