Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Общий форум

Страница: 1 |

 

  Вопрос: Считать случайную строку... Добавлено: 28.04.08 20:08  

Автор вопроса:  Boconon | Web-сайт: microsoft.com | ICQ: 216390557 
...я почему-то не могу.

Как прочитать (желательно быстро) случайную строку из текстового файла?

Я открывал файл, считал кол-во строк столь тупым методом \/
(если объясните нормальный метод, вместо сего извращенного, представленного ниже, буду очень благодарен).


Open "C:\somefile.txt" for input as #1
Dim i As Long
dim ggg as string
Do Until EOF(1)
line input #1, ggg
i = i +1
Loop
Close #1


Потом генерил случайное число...


Dim x as long
x = Int(Rnd * i) ' i - кол-во строк в файле


И соответственно считывал строчку под номером x.
Выходит очень медленно.
Ничего умнее в голову не пришло.

Как это сделать поумнее?

Ответить

  Ответы Всего ответов: 13  

Номер ответа: 1
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #1
Добавлено: 28.04.08 20:23
Open "C:\somefile.txt" for input as #1
   Dim col As New Collection, ggg as string
   Do Until EOF(1)
      line input #1, ggg
      col.Add ggg
   Loop
Close #1
Далее просто берешь случайную строку из коллекции. Хотя если файл очень большой...
Строки в файле все разной длины?

Ответить

Номер ответа: 2
Автор ответа:
 Sur



ICQ: 1249088 

Вопросов: 10
Ответов: 304
 Web-сайт: sur.hotbox.ru/
 Профиль | | #2
Добавлено: 29.04.08 13:44
Может будет лучше тут использовать вместо текста базу данных или xml?

Ответить

Номер ответа: 3
Автор ответа:
 Александр



ICQ: 414713812 

Вопросов: 16
Ответов: 49
 Профиль | | #3 Добавлено: 29.04.08 23:18
Тут лучше использовать динамический массив:

Dim stroki() As String
Dim col As Integer
Dim tmp As String
Sub progr()
col = -1
Open ";D:\1.txt" For Input As #1
Do While Not EOF(1)
Line Input #1, tmp
col = col + 1
Loop
Close #1
'посчитал строки
ReDim stroki(col)
col = -1
Open ";D:\1.txt" For Input As #1
Do While Not EOF(1)
col = col + 1
Line Input #1, stroki(col)
Loop
Close #1

Randomize
' это полюбому иначе нифига толку от rnd не будет
MsgBox stroki(Rnd * col)

End Sub

Ответить

Номер ответа: 4
Автор ответа:
 Александр



ICQ: 414713812 

Вопросов: 16
Ответов: 49
 Профиль | | #4 Добавлено: 29.04.08 23:31
А так ещё умнее)))
Dim stroki() As String
Dim col As Integer
Dim tmp As String
Sub progr()
col = -1
Open ";D:\1.txt" For Input As #1
Do While Not EOF(1)
col = col + 1
ReDim Preserve stroki(col)
Line Input #1, stroki(col)
Loop
Close #1
'посчитал строки
Randomize
' это полюбому иначе нифига толку от rnd не будет
MsgBox stroki(Rnd * col)
End Sub

Ответить

Номер ответа: 5
Автор ответа:
 Winand



Вопросов: 87
Ответов: 2795
 Web-сайт: winandfx.narod.ru
 Профиль | | #5
Добавлено: 30.04.08 00:08
а вот и нифига! Rnd = 0.643 Col = 2 и что это за индекс такой 1.286 =))))

Ответить

Номер ответа: 6
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #6
Добавлено: 30.04.08 01:30
Ну а если совсем по уму, то надо открывать файл в бинарном режиме, читать все, потом искать кол-во строк в нем, потом рекурсивно ищем следующее вхождение vbCrLf, когда нашли нужное кол-во - ищем следующее вхождение и результатом выдаем то, что будет между последним и предпоследним vbCrLf. Если правильно организовать, то будет быстрее стандартных функций работы с файлами и массивами типа Line Input и Redim Preserve

Ответить

Номер ответа: 7
Автор ответа:
 J. Smith



ICQ: ненавижу 

Вопросов: 40
Ответов: 477
 Web-сайт: Не хочу ломать голову, если её уже сломал кто-то другой.
 Профиль | | #7
Добавлено: 30.04.08 11:30
А так не проще?

Dim tmpArr() as String
Dim tmpBin as String
Open MyFile For Input As 1
    tmpBin = Input(LOF(1), #1)
Close
tmpArr = Split(tmpBin, vbCrLf)

СлучайнаяСтрока = tmpArr(Rnd * ubound(tmpArr))

Ответить

Номер ответа: 8
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #8
Добавлено: 30.04.08 12:30
Так может и проще, но не факт что быстрее - это раз; новая строка это не всегда vbCrLf - это два; СлучайнаяСтрока = tmpArr(int(Rnd * ubound(tmpArr))) - это три.

Ответить

Номер ответа: 9
Автор ответа:
 J. Smith



ICQ: ненавижу 

Вопросов: 40
Ответов: 477
 Web-сайт: Не хочу ломать голову, если её уже сломал кто-то другой.
 Профиль | | #9
Добавлено: 30.04.08 13:16
нет бы написать свой пример сверхскоростной рекурсии причем сразу на си чтоб ещё быстрее :)
Тут скорость зависит от первого чтения с винта, и я хотел чтоб он сам додумал элементарные ошибки.

Ответить

Номер ответа: 10
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #10
Добавлено: 30.04.08 13:49
Ну-ну =) От винта, конечно, зависит многое.... Но и стандартные функи васика жутко тормозят. А для подобных целей я бы сделал ассемблерную вставку.

Ответить

Номер ответа: 11
Автор ответа:
 J. Smith



ICQ: ненавижу 

Вопросов: 40
Ответов: 477
 Web-сайт: Не хочу ломать голову, если её уже сломал кто-то другой.
 Профиль | | #11
Добавлено: 30.04.08 13:56
Но и стандартные функи васика жутко тормозят.

Согласен, Васёк воще вселенский тормоз :) зато простой как валенок

Ответить

Номер ответа: 12
Автор ответа:
 J. Smith



ICQ: ненавижу 

Вопросов: 40
Ответов: 477
 Web-сайт: Не хочу ломать голову, если её уже сломал кто-то другой.
 Профиль | | #12
Добавлено: 30.04.08 14:01
сори за офтоп
голова дырявая, забыл уже
не помниш как это правильно было

Call SendKeys("{Ctrl}+V";)

не работает

Ответить

Номер ответа: 13
Автор ответа:
 



Администратор

ICQ: 278109632 

Вопросов: 42
Ответов: 3949
 Web-сайт: domkratt.com
 Профиль | | #13
Добавлено: 30.04.08 14:12
SendKeys "^V"

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам