Страница: 1 | 2 |
Вопрос: Алгоритм быстрой обработки текста?
Добавлено: 27.02.08 01:11
Автор вопроса: Oleg
Есть такой текст:
[Restrict]
Nod=40
TraffPoints=39,40,39
TraffRoads=10,10
Time=
[END-Restrict]
[POLYLINE]
Type=0x1
EndLevel=2
RoadID=58
Data0=(50.46900,30.49562),(50.47145,30.50012),(50.47118,30.50743),(50.47354,30.51049)
Nod1=0,48,0
Nod2=3,47,0
[END]
[POLYLINE]
Type=0x1
EndLevel=2
RoadID=59
Data0=(50.47232,30.48033),(50.47263,30.48692),(50.47328,30.49340),(50.47251,30.49730)
Nodes0=(0,49),(3,50)
[END]
И вот такого текста около 70мб
Требуется найти в этом тексте все выделенные жирным Nod1=0,48,0 и TraffPoints=39,40,39 и перенумеровать эти числа по порядку от заданого числа.
Все что я придумал в VB.NET:
1. Загружаю в переменную файл
2. Прохожу регекспом нахожу и создаю сортированный массив Generic.List с уникальными номерами
3. Разрезаю файл-переменную по 10мб чтобы не ругался на нехватку памяти при изменениях
4. Перебираю массив и регекспом меняю в тексте найденные из массива числа
5. сливаю в файл куски
При таком подходе файл в 70мб обрабатывается в течении 10-12 часов
Может есть какой способ делать это быстрее средствами VB?
Ответы
Всего ответов: 23
Номер ответа: 1
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #1
Добавлено: 27.02.08 04:02
Не понял я, по какому принципу ты выделяешь что-то жирным
Номер ответа: 2
Автор ответа:
grafff
Вопросов: 1
Ответов: 6
Профиль | | #2
Добавлено: 27.02.08 13:25
Этот текст это карта в текстом формате.
То что жирным это номера узлов объектов.
Они уникальны но встречаются очень часто в разных во множестве мест текста, в основном в строках:
Nod1=0,48,0 и TraffPoints=39,48,39
Незнаю, понятно обьяснил?
Номер ответа: 3
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #3
Добавлено: 27.02.08 16:05
Ты не догнал!
Это задача... На реверсинг формата! ))
Номер ответа: 4
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #4
Добавлено: 27.02.08 22:08
Ну уж это надо написать, а не предоставить догадываться
Кто мешает просто составить таблицу соответствия старых идов новым, и за проход по таблице поменять старые на новые? И не надо все это грузить в память.
Номер ответа: 5
Автор ответа:
grafff
Вопросов: 1
Ответов: 6
Профиль | | #5
Добавлено: 28.02.08 16:57
А можно вот отсюда поподробнее?
Что такое иды?
И как все это не грузить в память?
Номер ответа: 6
Автор ответа:
grafff
Вопросов: 1
Ответов: 6
Профиль | | #6
Добавлено: 28.02.08 17:43
А я понял, ты имел ввиду id!
Так я так и делаю:
Загоняю в массив номера
Потом прохожу по массиву и подставляю вместо значения ключа счетчик.
Но проблема в том что строка в ВБ при изменении хоть какомто (пменять букву) меняется вся целиком.
А если это строка 10-20мб, а в массиве 20000 значений для замены? Память забивается под горло.
Вот и хочу вас спросить может есть способ ускорить замену не через строковую переменную? Или как-то еще?
Номер ответа: 7
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #7
Добавлено: 28.02.08 23:01
Ну разбей по строкам в массив строк, например
Номер ответа: 8
Автор ответа:
grafff
Вопросов: 1
Ответов: 6
Профиль | | #8
Добавлено: 29.02.08 14:32
Ты думаешь это будет быстрее?
А кто знает как сделать чтобы заработал StringBuilder с регекспами?
Выдает ошибку что регексп неможет работать с данным типом!
Номер ответа: 9
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #9
Добавлено: 03.03.08 08:40
Регулярные выражение не могут со StringBuilder работать.
Если у тебя данные лежат в StringBuilder, то можешь получить из него строку методом ToString, никакого увеличения скорости это не даст.
Регулярные выражения - далеко не самый быстрый способ, зато самый простой.
Можно написать свой синтаксический аналзатор и работать он будет в 10-100 раз быстрее, разумеется, кол-во строк кода тоже будет намного больше.
Номер ответа: 10
Автор ответа:
Oleg
Вопросов: 1
Ответов: 7
Профиль | | #10
Добавлено: 03.03.08 14:13
Количество строк кода не важно, важно чтобы быстрее работало!
Анализатор, это через InStr, Replace и т.д.?
Я вижу 2 главные тормозящие проблемы:
1. Я загоняю в переменную весь файл как строку. Потом делю ее на на части и обрабатываю части.
Может можно както по другому?
2. Это поиск и замена в тексте подстрок.
Здесь массив получается с того на что поменять очень большой 10000-50000. Соответственно это является количеством проходов по всему тексту. Плюс к этому если обрабатывать не регулярными выражениями на каждый проход добавится еще и колличество замен через Replace.
Может что конкретнее посоветуете?
Номер ответа: 11
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #11
Добавлено: 03.03.08 15:17
Мне не совсем ясен формат файла и что требуетс сделать....
Под анализатором я имею в виду перебор char'ов (быстрее вряд ли получится)
Посоветовать что-либо конкретное можно было бы, но формат мне не ясен.
Номер ответа: 12
Автор ответа:
Oleg
Вопросов: 1
Ответов: 7
Профиль | | #12
Добавлено: 03.03.08 18:15
Формат текстовый.
Сотри первый пост, из такой инфы состоит весь файл.
Номер ответа: 13
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #13
Добавлено: 03.03.08 18:21
то что формат текстовый это ясно.
Объяснение формата мне не понятно, если есть желание, объясни более подробно, я додумываться что ты где имеешь в виду не буду.
Номер ответа: 14
Автор ответа:
Oleg
Вопросов: 1
Ответов: 7
Профиль | | #14
Добавлено: 03.03.08 18:56
Вот полный файл тест:
http://rapidshare.com/files/96746511/karta.zip.html
Это карта в текстовм "Польском формате"
В этой карте есть линии, точки, полигоны.
Линии это секция между [POLYLINE] и [END]
У линий есть узлы по вершинам линий, описвается строкой
Data0=(50.44879,30.48224),(50.45882,30.48638)
где указываются координаты.
Также у линий роутовые узля для автоматической прокладки маршрута Nod1=0,102,0
Где Nod(номер узла по порядку в блоке)=номер узла по порядку в линии, номер узла по порядку в карте, идентификатор обозначающий внешний узел или нет.
Такхе есть секция
[Restrict]
Nod=102
TraffPoints=103,102,103
TraffRoads=2,2
Time=
[END-Restrict]
где описываются запреты поворотов для роутового узла. Nod=номер узла для которого описывается правило TraffPoints=номер узла,номер узла,номер узла
При добавлении новой линии в карту и установки роутового узла в ней, узлу назначается уникальный номер по счетчику в карте от наибольшего Nod1=0,102,0. Но если скопировать линию из другой карты и вставить в эту и в узле будет номер намного больше последнего номера фрагментируются.
К примерру было 1,2,3,4,5 добавили 12,13,14 последним номером станет 14!
Так вот задача стоит в том чтобы привести счетчик в порядковый вид 1,2,3,4,5,6,7,8. Тоесть пройтись по всем номерам и переписать их по порядку.
Вот только текста такого от 20-70мб
Номер ответа: 15
Автор ответа:
Artyom
Разработчик
Вопросов: 130
Ответов: 6602
Профиль | | #15
Добавлено: 03.03.08 22:44
Вроде ясно.
По сути будет два перебора.
На первом собираешь все идентификаторы в отдельный список, далее второй цикл - переливаешь свои данные в StringBuilder, заменяя идентификаторы соответствующей им позицией в списке.
В принципе несложно, но гораздо сложнее чем регулярными выражениями.