Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  

Показать сообщение отдельно

Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


Creat0R
Цитата:
Удаляются не все дублирующиеся блоки
ёлы-палы, такую грубую ошибку прозевал!... функция _DupURLsInArray возвращала неотсортированные данные, а это как известно перепутывает индексы при удалении, профиксил.

Ладно, коли такое дело переделал функцию - теперь она возвращает начало и конец продублированных блоков (от содержания строки отказался, т.к. невостребовано). Далее - предыдущий вариант страдал нелогичностью по отношению к операциям ввода-вывода, то смотрим в массив, то в файл.... зачем тогда было его загружать?.. Поэтому все операции с файлом (в т.ч. удаление строк) переделал для массива, в заключении готовый массив выгружается поверх старого файла:
Код: Выделить весь код
#include <File.au3>
#include <Array.au3>

$File = "c:\test.txt"

Dim $FileLines
_FileReadToArray ($file, $FileLines)
; Возвращаем данные о дублирующихся блоках
$DupLines = _DupBLKsInArray ($FileLines, '#URL', @TAB & 'URL=')
; Страховка от пустого массива если дублей нет
If $DupLines [0][0] >0 Then
    For $i=$DupLines [0][0] To 1 Step -1
        For $j=$DupLines [$i][1] To $DupLines [$i][0] Step -1
            _ArrayDelete ($FileLines, $j)
        Next
    Next
    _FileWriteFromArray($File, $FileLines, 1)
EndIf

; Возвращает отсортированный двумерный массив со счетчиком, содержащий
; начало и конец продублированных блоков, в качестве параметров принимаются
; строки, отмечающие начало блока и начало ключевой строки
Func _DupBLKsInArray (ByRef $array, $BlkStartLine, $BlkKeyLine)
    Local $i, $i, $BlkStart, $res [1][2] = [[0,0]]
    Local $BlkStartLen= StringLen ($BlkStartLine)
    Local $BlkKeytLen = StringLen ($BlkKeyLine)
    ; рабочий массив для отметки обработанных дублей
    Local $flags [$array [0] +1]
    For $i=1 To $array [0]
        If StringLeft ($array [$i], $BlkKeytLen) = $BlkKeyLine Then
            For $j=$i+1 To $array [0]
                If StringLeft ($array [$j], $BlkStartLen) = $BlkStartLine Then
                    ; отмечаем начало текущего блока
                    $BlkStart = $j
                    ; если у текущего дубля нет конца, значит это он и есть
                    If $res [$res [0][0]][1] =0 Then $res [$res [0][0]][1] = $BlkStart -1
                EndIf
                If $flags [$j] <> 1 Then
                    If $array [$i] = $array [$j] Then
                        ReDim $res [$res [0][0]+2][2]
                        $res [0][0] = $res [0][0] +1
                        ; вспоминаем начало текущего блока
                        $res [$res [0][0]][0] = $BlkStart
                        $res [$res [0][0]][1] = 0
                        $flags [$j] = 1
                    EndIf
                EndIf
            Next
            ; если конца до сих пор не нашли, значит этот блок последний
            If $res [$res [0][0]][1] =0 Then $res [$res [0][0]][1] = $j-1
        EndIf
    Next
    ; сортировка массива по возрастанию
    _ArraySort ($res, 0, 1, 0, 2)
    Return $res
EndFunc

Последний раз редактировалось amel27, 13-11-2006 в 12:38. Причина: косметические мелочи

Это сообщение посчитали полезным следующие участники:

Отправлено: 08:32, 10-11-2006 | #461