Форум
Написать нам
  • Страница 1 из 1
  • 1
Модератор форума: as-master  
Скрипт выборочного формирования списка
as-masterДата: Воскресенье, 08 Июля 2007, 16:32 | Сообщение # 1
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
У меня имеется словарь, составленный по такой структуре:

АБАКУМЫЧ - ломик
АБАС - двадцатикопеечная монета
АБВЕР - опеpативная часть
АБДАСТА - пистолет
АБИССИНСКИЙ НАЛОГ - дача взятки
и т.д.

Все определения написаны ОБЯЗАТЕЛЬНО в одну строку.
Мне нужно сформировать список, в котором были бы только слова, без определений:

АБАКУМЫЧ
АБАС
АБВЕР
АБДАСТА
АБИССИНСКИЙ НАЛОГ
и т.д.

И решил я сделать это так. Сначала весь словарь заносим во вспомогательный список SongList1.
Затем формируем основной список, SongList, по такому вот сценарию:

ListBoxGetItems("SongList1","Items$,NumItem$,#,N")
For i=1 ToN
it$=GetArrayItem(Items$,#,i)
** Ищем позицию пробела с тире:
a$=' -'
p=POS(a$,it$)
** Оставляем только нужное:
it$=StrCopy(it$,1,p)
** И заносим это в список:
ListBoxAddItem("SongList","it$")
Next i

Здесь всё понятно. Однако работает такой скрипт крайне медленно.
При том, что в словарях у меня по 5-7 тысяч строк, программа зависает.
С одной-двумя тысячами еще работает, но список формируется крайне
медленно.

ВОТ И ВОПРОС. Нет ли каких идей сценария, чтобы сформировать
такой список побыстрее, раз эдак в 10-30? :)


Да пребудет с вами ММВ!
 
Alex3AДата: Воскресенье, 08 Июля 2007, 23:10 | Сообщение # 2
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
А ListBox обязателен?(SongList1)
получается что мы заносим массив в ListBox, потом его обрабатываем, а затем
добавляем в другой (SongList).
ListBox - крутой визуальный объект, а потому медленный, нельзя ли поработать с массивом?
Ну это так, на первый взгляд, надо посмотреть возможности скриптов ммв.
 
as-masterДата: Понедельник, 09 Июля 2007, 09:29 | Сообщение # 3
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Ну как я обойдусь без листбокса? Мне ведь надо прокручивать словарь,
щелкать на пунктах, при этом будут выводиться определения слов
в другом окне...

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

Добавлено (09 Июля 2007, 09:29)
---------------------------------------------
Дело в том, что метод формирования списка в цикле ничего хорошего не даст.
В цикле пункты в список добавляются по одному, и после добавления каждого
нового пункта список обновляется, как бы делая Refresh, причём независимо
от того, хочешь ты этого или нет. И избавиться от этого нельзя.

Поэтому всё и тормозит в моём примере.

А значит, список нужно формировать СРАЗУ, в один приём, типа командой:

ListBoxAddItem("SongList","path$"), где path$ - путь к файлу.

Поэтому я придумал другой способ формирования списка, где используется
только один объект SongList, а не два.

Для этого мы формируем новый файл, выдергивая из старого по одной
строке, из каждой строки извлекаем нужное и записываем эту строку
к новый файл. Вот сценарий (здесь path$ - путь к файлу словаря):

Code
nol=NOL(path$)
** Задаем путь к файлу НОВОГО словаря:
word$='<Temp>\word.txt'
For i=1 To nol
    ** Извлекаем строку:
    str$=StrFromFile(path$,i,1)
    ** Ищем позицию пробела с тире:
    a$=' -'
    p=POS(a$,str$)
    p=p-1
    ** Оставляем только нужное:
    str$=StrCopy(str$,1,p)
    ** Записываем строку в новый файл
    RV=StrToFile(word$,str$,TRUE,TRUE)
Next i
** Ну и потом одним махом формируем список:
ListBoxAddItem("SongList","word$")

Список-то формируется секунды за 3-4, но вот сам процесс извлечения
и записи строк все равно идет очень долго - секунд 15. Правда, тот скрипт,
который я привел в начале, вообще подвешивал программу, не доходя
до конца. Он работал только если в словаре раз в 10 поменьше слов.

Теперь сижу и думаю: а не лучше ли сделать ДВА словаря: один полный,
по которому будет проводиться поиск, а второй словарь, содержащий только
слова без определений, использовать для загрузки в список???...


Да пребудет с вами ММВ!
 
YURIYДата: Понедельник, 09 Июля 2007, 12:21 | Сообщение # 4
Злостный админ
Группа: Администраторы
Сообщений: 3018
Репутация: 71
Награды: 28
Статус: Offline
Попробуй так... Но всё равно долго у меня обрабатывались 7000 строк... Хотя, этот вариант полностью без СонгЛистов:

Code
lines=NOL(C:\Base.txt)
For i=1 To lines
   file$=StrFromFile(C:\Base.txt, i, 1)
   p=POS(' -',file$)-1
   file$=StrCopy(file$,1,p)
   ListBoxAddItem("SongList","file$")
Next i

C:\Base.txt - моя база.



Вечная память Андрею Сергееву!
 
as-masterДата: Понедельник, 09 Июля 2007, 12:26 | Сообщение # 5
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Спасибо, конечно.
Но всё равно, как я уже заметил, формирование списка В ЦИКЛЕ
никуда не годится... Он ведь обновляется после каждого добавления.


Да пребудет с вами ММВ!
 
Alex3AДата: Понедельник, 09 Июля 2007, 12:50 | Сообщение # 6
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
**считываем файл, первая строка содержит количество строк в файле
dlina$=StrFromFile('<SrcDir>\count.txt',1,1)
**переводим в число
dlina=VAL(dlina$)
**считываем строки и обработав заносим в массив
For a=2 To dlina **начинаем со второй строки - первая содержит
** количество строк в файле
stroka$=StrFromFile('<SrcDir>\22.txt',a,1)**берем по одной строке
rezult$=**тут обрабатываем полученную строку
Returnarray$[a]=rezult$
**и заносим результат в массив
Next a
**обработанный массив готов
**или если надо формируй текст
**функцией StrToFile делаешь обратную операцию,
**все это добро сохраняешь в файл
P.S.
Надо посмотреть, запихуется ли в листбох сразу массив или текст, ну я не помню!
Quote
и записи строк все равно идет очень долго - секунд 15.

Попробуй не извлекать из листа текст, а считывать только номер выделеной строки,
а текст бери из массива.
 
as-masterДата: Понедельник, 09 Июля 2007, 13:52 | Сообщение # 7
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Ну, во-первых, это всё работает тоже около 15 секунд
для файла из 7000 строк.

А во-вторых, так и не ясно: как же сформировать после всего этого
список? Надо было написать конкретный сценарий!

Пока я не нашел решения, остановился на варианте
с использованием двух словарей - полного и только со словами.


Да пребудет с вами ММВ!
 
humanoidДата: Понедельник, 09 Июля 2007, 14:07 | Сообщение # 8
Гуманоид
Группа: Проверенные
Сообщений: 406
Репутация: 3
Награды: 1
Статус: Offline
Советовать конечно глупо, но мне кажется , что пытаешся опять всучить программе совешенно неудобоваримые вещи... не будет движок MMB обрабатывать очень большие массивы информации по запросу достаточно быстро, она для этого не создана...

Существуют специальные заточенные под это дело вещи... например простейший MS Access – (если ты умеешь работать и формировать таблицы Ацесс, то для тебя не составит ни какого труда создать базу данных с необходимым контентом, включая по-символьный ввод искомый данных, а Aцесс будет моментально отбражать вводимые данные... и не важно 100 mb информации или больше)

Вот примеры, что-то типа такого что ты подразумеваешь сделать – Словарь жаргонных слов и Выражений (кстати у меня есть пособие 75 года для служебного ментовского пользования – как раз такой словарик, но как мне кажется он безнадежно устарел)..

http://vfiles.uploadingit.com/ufiles/21000/BD.zip

Первый не совсем рабочий пример... так как нет времени создавать хотя бы 10% рабочую базу... это так для иллюстрации...

А вот второй пример... как раз попытка объединить MMB, с Access - я особо не вникал в подробности этой затеи, но видимо чего-то там получается... но это не совсем то, что тебе надо, но возможно это наведет тебя на некоторые мысли...

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

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


Hi, from Moon!
 
as-masterДата: Понедельник, 09 Июля 2007, 14:14 | Сообщение # 9
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Quote (humanoid)
пытаешся опять всучить программе совешенно неудобоваримые вещи...
не будет движок MMB обрабатывать очень большие массивы информации


Формирование списка - это не "неудобоваримые вещи", это как раз
прямые обязанности ММВ :) Другое дело, если текстовый файл словаря
действительно очень большой, от мегабайта и выше. Я же специально
взял словарь небольшого размера, понимая, что словарь Даля на ММВ
не сделать.

За пример спасибо, качну его вечерком, когда перейду с трафика на модем.


Да пребудет с вами ММВ!
 
humanoidДата: Понедельник, 09 Июля 2007, 14:41 | Сообщение # 10
Гуманоид
Группа: Проверенные
Сообщений: 406
Репутация: 3
Награды: 1
Статус: Offline
Quote
"неудобоваримые вещи"

Quote
не будет движок MMB обрабатывать очень большие массивы информации по запросу достаточно быстро, она для этого не создана...

Я про оочень большие данные и говорил...

Quote
качну его вечерком, когда перейду с трафика на модем

там зипа то ~500 kb dry


Hi, from Moon!
 
YURIYДата: Понедельник, 09 Июля 2007, 14:50 | Сообщение # 11
Злостный админ
Группа: Администраторы
Сообщений: 3018
Репутация: 71
Награды: 28
Статус: Offline
Alex3A, вы сделали тоже самое, что и я, только в сто раз сложнее..

Как я успел понять, MMB никак не подходит для работы со строками... Только элементарные вещи.

А Гумир дело говорит. Здесь лучше сделать плагин для работы с SQLite и будет класс! Я могу модуль также сделать. С базами данных удобно работать. А SQLite отличается своей быстротой и лёгкостью. Его библиотека весит 340 КБ без сжатия. Без неё, естессно, не сможешь работать.

Ну а вообще... Раз MMB так работает со строками, то лучше, конечно, сформировать отдельный файл с преобразованными словами. Причём, я бы сделал так, чтобы место зря не занимать. Первый файл содержит слова до "-", второй - после. А не первый - все слова, а второй только после преобразований.



Вечная память Андрею Сергееву!
 
as-masterДата: Понедельник, 09 Июля 2007, 15:18 | Сообщение # 12
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Quote (Yuriy)
Первый файл содержит слова до "-", второй - после

Так не получится. Второй файл должен содержать ВСЁ!!!
Почему? Потому-что в нём производится поиск по запросу.
И если он не будет содержать этих слов, то как тогда искать?

А вот первый файл нужен всего лишь для отображения словаря
в программе, и для автоматического поиска при выделении в нем
слова. То есть: из этого файла загружается в список, при щелчке по
пункту слово автоматически вставляется в ЭдитБокс и запускается
скрипт поиска.

Будем считать, что проблему решить по-другому невозможно:
хоть так, хоть эдак - работает медленно. Только с двумя словарями
работает нормально.

Народ, лучше помогите мне в теме Как определить номер строки !!!

PS. А насчет плагина или модуля - я только обеими руками за!
Главное - чтоб размерчик, как всегда...


Да пребудет с вами ММВ!
 
Alex3AДата: Понедельник, 09 Июля 2007, 21:49 | Сообщение # 13
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
Quote
Alex3A, вы сделали тоже самое, что и я, только в сто раз сложнее..

Да нет, практически тоже что и ты, только с коментариями, а длина в начале файла -
тяга к протоколам, и вообще полезная вещь, при. ну, очень больших объемах,
возможно добавлять иную полезную информацию, разбивать файлы до меньшего размера,
делать динамическую загрузку, зачем в лист засовывать тысячи строк, пару десятков и хватит.
Остальное подгружать по необходимости.
Просто не видел твой ответ, и первоначально кинул не в ту ветку.
Тут, кардинально может помочь только плагин, вся работа в плагине происходит вне
контекста проекта ммв, поэтому тормозить проект не будет.
При таком количестве строк будет задумыватся любой скриптовый интерпритатор.
Если до среды успею наваять, выложу (убываю к морям, в командировку, правда
не уверен увижу ли море, на пару недель). Надо найти исходники.
(проблема как у toizy смотри в соотв. ветке)
Где то были, стандартный, с фоном из внешнего файла и типа прозрачный - фон ворованный
из ммв страницы. Это на коле, так что размер будет небольшой, правда не все сойства листа
еще разобрал, интузиазизм пропал и поездки мешают. Ну, а на вецееле поболее.
Я так понимаю, основное время идет на запихивание в лист а не на обработку?
AS, кинь по мылу пожелания.
Обработку текста можно делать в плагине, быстро будет. Подумай о передаче в ммв - вот здесь
слабое место загибается токи так!
Плагин будет запускать скрипт, в свойствах плагина ммв, придумай по какому событию,
или нескольким - при запуске считывай цифру из плагина - узнаешь какое событие произошло,
и что в текстовой переменной, или наоборот. Договоримся.
 
Alex3AДата: Вторник, 10 Июля 2007, 09:28 | Сообщение # 14
Друг клуба ММВ
Группа: Проверенные
Сообщений: 2646
Репутация: 39
Награды: 11
Статус: Offline
Quote
Главное - чтоб размерчик

На, пробуй, незабудь поставить интернал плеер!
Извращения потом зделаю.
Прикрепления: 33450435.rar (17.7 Kb)
 
RushДата: Вторник, 10 Июля 2007, 16:09 | Сообщение # 15
Обозреватель-консультант
Группа: Проверенные
Сообщений: 216
Репутация: 10
Награды: 1
Статус: Offline
На первый взгляд - без цикла не разделить. Что неизбежно очень тормозит всё.
Надо подумать об обходных путях. Но что-то сомнения берут...

Добавлено (10 Июля 2007, 16:09)
---------------------------------------------

Quote (as-master)
А значит, список нужно формировать СРАЗУ, в один приём, типа командой:
ListBoxAddItem("SongList","path$"), где path$ - путь к файлу.

Разделенный список можно загрузить в листбокс быстро. Естественно, без всяких циклов:
Code
SongListReset()
ListBoxAddItem("SongList","RESET")
SongListLoad("имя файла","txt")
ListBoxAddItem("SongList","<List>")
 
as-masterДата: Вторник, 10 Июля 2007, 16:34 | Сообщение # 16
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Quote (Rush)
Разделенный список можно загрузить в листбокс быстро.

Да, он и так тоже прекрасно загружается:

ListBoxAddItem("SongList","RESET")
ListBoxAddItem("SongList","path$")

А обходные пути, мне думается, вряд ли найдутся...


Да пребудет с вами ММВ!
 
RushДата: Вторник, 10 Июля 2007, 18:48 | Сообщение # 17
Обозреватель-консультант
Группа: Проверенные
Сообщений: 216
Репутация: 10
Награды: 1
Статус: Offline
А ведь я нашел обходной путь. :)))
Но он странный. Как и я...

Нужно после каждого слова-определяемого поставить точку.
Вот так:

АБАКУМЫЧ. - ломик
АБАС. - двадцатикопеечная монета
АБВЕР. - опеpативная часть
АБДАСТА. - пистолет
АБИССИНСКИЙ НАЛОГ. - дача взятки
и т.д.

Кстати, и в поиск как дополнительный параметр можно включать.
Но это, конечно, полдела. smile
Далее скрипт:

Code
SongListReset()
ListBoxAddItem("SongList","RESET")
SongListLoad("имя файла","m3u")
ListBoxAddItem("SongList","<List>")

Не зря же я его приводил.
Хотя, все равно загружается не ахти как быстро. Поэтому я бы посоветовал по буквам разделить словарь на файлы...

 
as-masterДата: Вторник, 10 Июля 2007, 20:21 | Сообщение # 18
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Quote (Rush)
m3u

Действительно m3u, а не txt?
Или это АПИЧЯТКА?


Да пребудет с вами ММВ!
 
RushДата: Среда, 11 Июля 2007, 00:51 | Сообщение # 19
Обозреватель-консультант
Группа: Проверенные
Сообщений: 216
Репутация: 10
Награды: 1
Статус: Offline
Quote (as-master)
Действительно m3u, а не txt?
Или это АПИЧЯТКА?

Так ведь именно в этом и есть вся фишка. Нужно поставить m3u или m3l. Тогда из строки будет браться только то, что находится до точки. Все, что за точкой, будет расценено как расширение. И отброшено.
 
as-masterДата: Вторник, 17 Июля 2007, 09:23 | Сообщение # 20
Разводящий
Группа: Модераторы
Сообщений: 2337
Репутация: 101
Награды: 5
Статус: Offline
Quote (Rush)
А ведь я нашел обходной путь. :))) Но он странный. Как и я...

Quote (Rush)
Так ведь именно в этом и есть вся фишка. Нужно поставить m3u или m3l.
Тогда из строки будет браться только то, что находится до точки. Все, что за точкой,
будет расценено как расширение. И отброшено.

Мне ничего не остаётся кроме того, как признать твою гениальность ;)

Добавлено (17 Июля 2007, 09:23)
---------------------------------------------
И еще один сценарий, который работает в полтора раза быстрее,
чем мой последний сценарий в этом топике. Хотя он всё равно
не решает проблему для длинных файлов:

Code
OpenFile("Открывай файл txt! (*.txt)","*.txt")
path$=OpenFile$
If (path$<>'') Then
   ** Очищаем листбокс:
   ListBoxAddItem("SongList","RESET")
   nol=NOL(path$)
   ** Задаем путь к файлу НОВОГО словаря:
   word$='<Temp>\word.txt'
   ** Очищаем файл нового словаря и переменные:
   str$=''
   string$=''
   RV=StrToFile(word$,str$,FALSE,FALSE)
   For i=1 To nol
     ** Извлекаем строку:
     str$=StrFromFile(path$,i,1)
     ** Ищем позицию пробела с тире:
     a$=' -'
     p=POS(a$,str$)
     p=p-1
     ** Оставляем только нужное:
     str$=StrCopy(str$,1,p)
     ** Добавляем символы переноса строки:
     str$=str$+CHR(13)+CHR(10)
     string$=string$+str$
   Next i
   ** Записываем строку в новый файл
   RV=StrToFile(word$,string$,TRUE,TRUE)
   ** Ну и потом одним махом формируем список:
   ListBoxAddItem("SongList","word$")
End


Да пребудет с вами ММВ!
 
  • Страница 1 из 1
  • 1
Поиск: