Сравнить два текстовых файла

Тема в разделе "Lotus - Программирование", создана пользователем -, 17 июл 2009.

Статус темы:
Закрыта.
  1. Гость

    Есть два файла.
    В одном 172353 текстовых строк,
    Во втором 13433 строки.

    Нужно выделить из строки первого файла бранд и номер и определить сколько номеров (по брандам) попало во второй файл, а сколько не попало.

    Я написала такую процедурку. Она работает, но медленно.
    1 запись из первого файла сравнивается со всеми записями из второго за секунду примерно...
    Есть ли возможность обработать эти данные быстрее?

    Код (Text):
    Sub Click(Source As Button)
    Dim text As String
    Dim fileAll As Integer, fileSort As Integer
    Dim PN_All As String, PN_Sort As String
    Dim brand As String, rec As String
    Dim PNcount As Double
    Dim brandList List As Double
    Dim num As Integer

    fileAll% = Freefile()
    Open "c:\GB_PRICE.CH2" For Input As fileAll%        'Список всех брандов и номеров
    fileSort% = Freefile()
    Open "c:\GB_ALL.NEW" For Input As fileSort%     'Список номеров прошедших фильтрацию
    fileSortRez% = Freefile()
    Open "c:\sortrez.txt" For Append As fileSortRez%    'Список брандов и кол-во номеров прошедших фильтрацию
    fileNoSortRez% = Freefile()
    Open "c:\nosortrez.txt" For Append As fileNoSortRez%    'Списко брандов и кол-во номеров непрошедших фильтрацию

    num = 1
    PNcount = 0     'Счетчик прошедших фильтрацию
    PNNocount = 0       'Счетчик непрошедших фильтрацию
    Do While Not Eof(fileAll%)
    'Получаем из файла бранд и номер текущий
    Line Input #fileAll%, text$
    brand = Left$(Mid$(text$, 178, 183),5)
    PN_All = Left$(text$, 7)

    'Если бранд новый, то записываем полученные значения в файл и обнуляем счетчики
    If (brandOld <> brand) Or (brandOld = "") Then 
    rec = brandold & " " & Cstr(PNcount)
    if brandOld <> "" then Write #fileSortRez%, rec
    rec = brandold & " " & Cstr(PNNocount)
    If PNNocount <> 0 Then Write #fileNoSortRez%, rec

    PNNocount = 0
    PNcount = 0
    PNoldcount = 0
    End If

    'Второй файл перематываем в начало
    Seek fileSort%, 1
    'Пока не конец файла сравниваем номера из него с запомненным номером
    Do While Not Eof(fileSort%)
    Line Input #fileSort%, text$
    PN_Sort = Left$(text$, 7)
    'Если находим номер в файле отфильтрованных, то увеличиваем счетчик прошедших фильтрацию
    If PN_All = PN_Sort Then
    PNcount = PNcount+1
    End If
    Loop

    'Если номер не найден, то увеличиваем счетчик непрошедших фильтрацию
    If PNcount = PNoldcount Then
    PNNocount = PNNocount + 1
    End If

    'Запоминаем значение счетчика прошедших фильтрацию и название текущего бренда
    PNoldcount = PNcount
    brandOld = brand

    'Выводим подсказку о номере строки которую сравнили
    num = num +1
    Print Cstr(num)
    Loop

    'Закрываем все файлы
    Close fileAll%
    Close fileSort%
    Close fileSortRez%
    Close fileNoSortRez%   
    End Sub
     
  2. Yakov

    Yakov Гость

    Считайте второй файл в List, используйте функцию IsElement().
     
  3. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    В декларации объявлен список. И это правильно. Тока он не используется...

    1. Пройтись один раз по втором файлу( который короче ) -
    Do While Not Eof(fileSort%)
    Line Input #fileSort%, text$
    PN_Sort = Left$(text$, 7)
    on error resume next ' в общем-то - необязательно, но все же...
    IDCountList( PN_Sort ) = IDCountList( PN_Sort ) + 1
    on error goto errhandle
    Loop
    Поимели список

    2. Пройтись по первому файлу:
    Do While Not Eof(fileAll%)
    'Получаем из файла бранд и номер текущий
    Line Input #fileAll%, text$
    brand = Left$(Mid$(text$, 178, 183),5)
    PN_All = Left$(text$, 7)

    if iselement( IDCountList ( PN_All ) ) then
    brandFoundList( brand ) = brandFoundList( brand ) + IDCountList ( PN_All )
    else
    brandNotFoundList( brand ) = brandNotFoundList( brand ) + 1
    end if
    Loop

    3. Имеем 2 списока.
    Первый: хэштаблица бранд-число вхождений во второй файл
    Второй: хэштаблица бранд - число номеров, не найденных во втором файле
    forall brand in brandFoundList
    ' пишем в файл прошедших
    end forall

    forall brand in brandNotFoundList
    ' пишем в один файл непрошедших
    end forall


    З.Ы. Т.к. первый файл похоже сортированный - можно не собирать списки а сразу писать в файл при смене текущего бранда. Экономим память.
     
  4. Гость

    Так примерно и сделала.
    Файлы не сортированные к сожалению.

    Спасибо!!!!! Работает 5 мин.
     
  5. Klido

    Klido Гость

    интересно, а если через API виндовое сделать - быстрее будет? как-то долговато 5 минут...
     
  6. turumbay

    Регистрация:
    13 мар 2009
    Сообщения:
    625
    Симпатии:
    2
    А это смотря как сделать. Использование апи ни коим образом не вылечит проблему симлинка /dev/hands на /dev/ass. :)

    5 минут - многовато, при условии, что проход по второму файлу в первоначальной версии занял 1 секунду.
    Если есть желание оптимизировать - то сначала ищем узкое место:
    для начала отделяем дисковые операции от операций с памятью - убеждаемся, что не уткнулись в производительность ФС. Если таки файловая система - то забиваем, ибо бессильны.
    если проблемы не с чтением/записью - то возможно(!) тормозят строковые операции.
    В общем, не зная деталей( не видя кода, который работает 5 минут ), любые выводы о путях оптимизации безосновательны.
     
  7. Гость

    Оно меньше чем за 5 минут работает. Это я приблизительно сказала. :)
    А так по ощущениям за 2 или полторы... не засекала.
     
  8. Klido

    Klido Гость

    тема грузануть в память файлы и там работать... из-под лотусины напрямую это не сделать...
    считывание 175К строк (это 175КХ100примерно в строке=аж 17Мб) 2 сек, на серваке с норм винтами 0.5 сек
    про скорость операций в оперативке мы не говорим :)
    вся задача СЧИТАТЬ и СРАВНИТЬ... а у нас такой большой код...
     
  9. lmike

    lmike нет, пердело совершенство
    Команда форума Lotus team

    Регистрация:
    27 авг 2008
    Сообщения:
    6.081
    Симпатии:
    300
    поиск в неупорядоченных данных не производительно делать прямым перебором... (есть методы ускоренного поиска)
    можно предварительно создать индекс строк 2-го файла (как минимум)

    использовать NotesStream - идеологически более правильно :)
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей