Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Файл и динамический массив


Страницы:   1 2

d3777 ©   (2006-04-05 18:07:00) 

есть текстовый файл. в нём матрица  чисел(несколько столбцов- m, и много-много строк - n). вопрос: как динамически выделить под него массив, точнее как определить размер этого массива?
для определения кол-ва стобцов делал read(F, W[m]) до конца первой строки - но это помоему не выход.
а со строками вообще не понял как. просто устанавливал с запасом. но это тоже не выход: так как кол-во строк от файла к фалу изменяется от 2 до 1048576.
заранее спасибо


Юрий Зотов   (2006-04-06 13:16:00) [1]

> Algol   (06.04.06 12:31) [38]

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


Юрий Зотов   (2006-04-06 13:10:00) [2]

> Algol   (06.04.06 12:31) [38]

Это пример, а не рабочая программа. Основное требование к примеру - он должен быть как можно более понятным. Так он и написан.


Algol   (2006-04-06 12:31:00) [3]

2ЮЗ
А зачем вы каждый раз открываете/закрываете файл?
Мне кажется во-первых это лишние операции, занимающие время, а во-вторых, это может помешать операционке оптимизировать доступ к файлу, при повторном его чтении. Я не прав?


Deka   (2006-04-06 11:25:00) [4]

Можно организовать одномерные массивы соотвествующие строкам. Такой массив создается при чтении строки. А сам массив добалять в список. При таком решении получится список массивов и однопроходная схема загрузки. Думаю что с памятью больших накладок не получится.
Можно еще попробовать определившись со структурой файла отобразить часть его в память и работать с ним как с готовым массивом.
Хотя наверное это вариант слишком сложен. Из пушки по воробьям, однако. Зато решается проблема нехватки памяти при большом файле.


Anatoly Podgoretsky   (2006-04-06 09:05:00) [5]

d3777 ©   (06.04.06 00:57) [26]
"В конце концов размер файла деленый на количество элементов в строке * 2 (один символ на пробел)"

может количество символов в строке подсчитывать?
но попадаются и односимвольные элементы массива (например просто 0),
0 один символ, разделитель 1 символ, итого два и еще есть запас за счет разделителей строк. Так ты не мудри а прочитай первые сто (или сколько считаешь нужным) строк, аппроксимируй и результат умножь на коэффициент.

Юрий Зотов ©   (06.04.06 01:51) [27]
Не то слово


Германн   (2006-04-06 02:32:00) [6]


> d3777 ©   (06.04.06 02:27) [34]
>
> в ручную надо страницу периодически обновлять


Через сколько ms советуешь её обновлять?


d3777   (2006-04-06 02:27:00) [7]

в ручную надо страницу периодически обновлять


Германн   (2006-04-06 02:18:00) [8]

Оп-ля :(
А как это? Прочитал, ответил. И узнал, что уже в прошлом веке все прочитали и кто-то ответил???


Германн   (2006-04-06 02:13:00) [9]


> d3777 ©   (06.04.06 02:01) [28]
>
> 2Юрий Зотов  ОГРОМНЕЙШЕЕ СПАСИБО за этот листинг!!!!!!!!
> !!!!!!!!!!!!!!!!!
>
> но только вот есть по моему маленькая загвоздка -  столбцы
> могут быть разделены несколькими пробелами :(
>


А ты уверен, что загвоздка есть?
По-моему строка  while (i <= Length(S)) and (S[i] in Separators) do
    Inc(i);

её решает.


d3777   (2006-04-06 02:12:00) [10]

ещё раз спасибо!!!!! и ещё раз извиняюсь за свою невнимательность


Юрий Зотов   (2006-04-06 02:07:00) [11]

> d3777 ©   (06.04.06 02:01) [28]

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

Внимательно посмотрите код, там есть цикл:
while (i <= Length(S)) and (S[i] in Separators) do
    Inc(i);

который пропустит любой набор любых разделителей в любом сочетании.


d3777   (2006-04-06 02:04:00) [12]

извиняюсь!!!!!!!!!! разобрался!!!!!! нет проблем :)


d3777   (2006-04-06 02:01:00) [13]

2Юрий Зотов  ОГРОМНЕЙШЕЕ СПАСИБО за этот листинг!!!!!!!!!!!!!!!!!!!!!!!!!

но только вот есть по моему маленькая загвоздка -  столбцы могут быть разделены несколькими пробелами :(


Юрий Зотов   (2006-04-06 01:51:00) [14]


procedure TForm1.FormCreate(Sender: TObject);
const
 FileName = 'C:\Numbers.txt';
 Separators = [ #9, ' ']; // Добавьте сюда любые возможные разделители
var
 F: TextFile;
 i, j, M, N: integer;
 S: string;
 A: array of array of integer;
begin
// 1. Создаем файл, не вручную же его набивать
 AssignFile(F, FileName);
 Rewrite(F);
 for i := 0 to 99 do  // 100 строк
 begin
   for j := 0 to 8 do // 9 столбцов
     Write(F, i, j, ' ');
   WriteLn(F, i, 9) // и еще один, 10-й столбец
 end;
 CloseFile(F);
// 2. Определяем кол-во столбцов N
 AssignFile(F, FileName);
 Reset(F);
 ReadLn(F, S);
 i := 1;
 N := 0;
 repeat
   while (i <= Length(S)) and (S[i] in Separators) do
     Inc(i);
   if i <= Length(S) then
   begin
     Inc(N);
     while (i <= Length(S)) and not (S[i] in Separators) do
       Inc(i)
   end
 until
   i > Length(S);
// 3. Определяем кол-во строк M
 M := 1;
 while not EoF(F) do
 begin
   ReadLn(F, S);
   Inc(M)
 end;
 CloseFile(F);
// 4. Заполняем массив повторным чтением файла.
 AssignFile(F, FileName);
 Reset(F);
 SetLength(A, M, N);
 for i := 0 to M - 1 do
 begin
   for j := 0 to N - 1 do
     Read(F, A[i, j]);
   ReadLn(F)
 end;
 CloseFile(F)
end;


И какие проблемы? Задачка для школьников, как видите.


d3777   (2006-04-06 00:57:00) [15]

2Anatoly Podgoretsky

Вот это не очень понятно:
"В конце концов размер файла деленый на количество элементов в строке * 2 (один символ на пробел)"

может количество символов в строке подсчитывать?
но попадаются и односимвольные элементы массива (например просто 0),
но наверно коэффициент запаса всё сгладит.......

З.Ы. вот я и пытаюсь найти этот разумный алгоритм :)


Джо   (2006-04-06 00:47:00) [16]

> и вообще, как определить вдруг там не таб, а несколько
> пробелов?

Символ табулятора имеет код 9, пробела — 32.


Anatoly Podgoretsky   (2006-04-06 00:45:00) [17]

Тогда аппроксимирование размера файла на количество строк, например по первым ста строкам с запасом на ошибку, например умножить расчетную величину на 1.3-1.5 и обрезанием по окончанию. Пересылки не будет, перераспределения не будет. Формат файла у тебя характерный длина чисел меняется незначительно. В конце концов размер файла деленый на количество элементов в строке * 2 (один символ на пробел), сработает даже для односимволным чисел. Все что нужно это избежать перераспределение памяти в процессе чтения файла. Будет максимальная скорость и не будет резкого расхода памяти при перераспределении при каждой иттерации. Просто нужен разумный алгоритм.


d3777   (2006-04-06 00:20:00) [18]

2Anatoly Podgoretsky
уже привёл в другом месте :)


Anatoly Podgoretsky   (2006-04-06 00:18:00) [19]

Привел бы формат файла, строк так 10 и максимальный предполагаемый размер файла. А то чего гадать.


d3777   (2006-04-06 00:16:00) [20]

замерил.........хех.............практика показала что второй вариант отметается сразу же (только у меня значения у первого около 1000тиков, у второго около 20000)

а иеперь глупый вопрос (просто никогда этим раньше не занимался):
1. Читаем первую строку целиком в строчную переменную S. Элементарный парсинг этой строки даст кол-во столбцов в массиве (кол-во разделителей плюс единица).
реализацию вот этого. точнее как табы искать в строке? и вообще, как определить вдруг там не таб, а несколько пробелов?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо