Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.04.2012, 21:48   #1
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Всем привет.
Есть массив данных, который считывается из бинарного файла с помощью TBinaryReader.
Вот структура данных (всего их 4, немного отличаются):
Код:
var BinPoints_20020715_time : packed record
PointCoordX: integer;
PointCoordY: integer;
PointCoordZ: integer;
PointCode: byte;
PointEcho: byte;
PointFlag: byte;
PointMark: byte;
PointLine: word;
PointInt:  word;
PointTime: cardinal;
end;
Далее в отдельной процедуре читаю по указанному формату:
Код:
procedure ReadBinPointsWithRecord(const FileName: String);
begin
with TBinaryReader.Create(FileName) do
try
BaseStream.Read(BinHeader, SizeOf(BinHeader));
begin
while basestream.Position<>basestream.Size do
begin//проверяем версию файла, если 20020715, то
if (BinHeader.HdrVersion=20020715) then
begin //есть время, нет цвета
if (BinHeader.Time>0) and (BinHeader.Color=0) then
begin
BaseStream.Read(BinPoints_20020715_time, SizeOf(BinPoints_20020715_time));
end
else //есть цвет и время
if (BinHeader.Time>0) and (BinHeader.Color>0) then
begin
BaseStream.Read(BinPoints_20020715_time_color, SizeOf(BinPoints_20020715_time_color));
end
else  //нет цвета, нет времени
BaseStream.Read(BinPoints_20020715_lite, SizeOf(BinPoints_20020715_time_color))
end
else  //устаревшая версия
BaseStream.Read(BinPoints_20010712, SizeOf(BinPoints_20010712));
end;
end;
finally
Free;
end;
end;
Теперь мне необходимо определиться наличие одинаковых данных. И далее либо их изменить, либо удалить, либо просто указать, что они вообще существуют.

Вопрос - с помощью чего вообще можно работать с такими данными?
Таблицу даже не рассматриваю - записей может быть несколько миллионов.

Может кто-нибудь чего подскажет?

В общем решил все грузить в TList, создавая отдельный класс для хранения в этом самом TList.
Данные туда грузятся и достаточно шустро, но вот как теперь искать дублирующиеся по параметрам строки мне пока не понятно.
Ну не считая так сказать грубой силы - прямой перебор всех записей в двойном цикле
Код:
procedure TForm1.Button1Click(Sender: TObject);
var i,j,k: integer;
begin
if RadioGroup1.ItemIndex=0 then
  begin
  k:=0;
  for i := 1 to Datalist.Count-1 do
  for j := i+1 to datalist.Count-1 do
  if (TPoint(DataList[i]).CoordX = TPoint(DataList[j]).CoordX)
  and (TPoint(DataList[i]).CoordY = TPoint(DataList[j]).CoordY)
  and (TPoint(DataList[i]).CoordZ = TPoint(DataList[j]).CoordZ)
  and (TPoint(DataList[i]).Time = TPoint(DataList[j]).Time)
  then  k:=k+1;
  if k=0 then
Showmessage('Нет') else
Showmessage('Есть ' + inttostr(k));
DataList.Clear;
  end;
end;
Работает конечно, но до невозможности долго - должны быть методы для быстрого вычисления...

Последний раз редактировалось Stilet; 18.04.2012 в 08:23.
Freimaks вне форума Ответить с цитированием
Старый 17.04.2012, 20:44   #2
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Несколько миллионов в TList? Нереально. Если, конечно, запись не размером в один-два байта.

Может быть так:
выбрать СУБД (FireBird, к примеру), загрузить всю инфу в БД, проиндексировав.
Одним запросом узнать есть ли и сколько дубликатных записей.
Прик вне форума Ответить с цитированием
Старый 17.04.2012, 21:18   #3
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Цитата:
Сообщение от Прик Посмотреть сообщение
Несколько миллионов в TList? Нереально. Если, конечно, запись не размером в один-два байта.

Может быть так:
выбрать СУБД (FireBird, к примеру), загрузить всю инфу в БД, проиндексировав.
Одним запросом узнать есть ли и сколько дубликатных записей.
Я думал о СУБД, но посчитал это менее логичным решением, нежели TList. Видимо ошибся. Завтра подумаю над СУБД.
А почему именно FireBird????

P.S. запись конечно не 1-2 байта, а десятки байт :-) и таких записей могут быть миллионы...

Прочитал про FireBird - вообще не хотелось бы подключать стороннюю СУБД, т.к. прога должна пахать просто при наличии exe-файла и без лишних движений...

Последний раз редактировалось Freimaks; 17.04.2012 в 21:30. Причина: Прочитал про FireBird
Freimaks вне форума Ответить с цитированием
Старый 17.04.2012, 21:44   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В FireBird есть вариант работы с базой без установки СУБД. Без провайдера правда не обойдешься, устанавливать прийдется
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 17.04.2012, 21:44   #5
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Почему FB? Не знаю почему. Наверное, потому что знаю получше.

И еще потому, что сервер СУБД Firebird можно установить у себя для разработки, а на сторонних машинах использовать "монопольный" (embedded) сервер, который не требует установки. Да и установка сетевого сервера FB занимает 3 минуты, из которых 2,5 уходят на осмысления флажков установщика, которых не так и много.

А главное, получить достаточно быстро требуемые данные из массива большого объема можно только на SQL СУБД (любой, разумеется, но современной).

-------------
Аватар, а про какого провайдера речь? Я что-то пропустил?
Прик вне форума Ответить с цитированием
Старый 17.04.2012, 21:50   #6
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Вот щас читаю про СУБД - я первый и последний раз под СУБД писал еще в универе.
Просто цель проги такова:
1. Читаем записи из бинарного файла;
2. Анализируем на наличией дублирующихся данных;
3. Производим действие по требованию (удаление или изменение) над дублями;
4. Пишем в новый бинарник.
Вот читать и писать - это не самая большая проблема. Проблема - как реализовать пункты 2 и 3. Я уже 3 дня думаю над этим...

Вот есть TClientDataSet, якобы встроенная СУБД, не требующая больше никаких телодвижений.

Последний раз редактировалось Freimaks; 17.04.2012 в 21:56.
Freimaks вне форума Ответить с цитированием
Старый 17.04.2012, 21:57   #7
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Печальный опыт реализации пункта 2 у вас уже есть.
Слабое звено здесь - поиск записей имеющих дубликатные значения в каких-то полях. Помощь в этом (ИМХО, конечно) может оказать SQL СУБД, которая как раз и заточена для максимально быстрого поиска в данных.
1. Читаем записи из файла и одновременно сливаем их в БД
2. Формируем SQL запрос на наличие дубликатов.
3. Формируем запросы по требованию на модификацию строк в БД
4. Читаем из БД данные и пишем в файл.
Прик вне форума Ответить с цитированием
Старый 17.04.2012, 22:04   #8
Freimaks
Пользователь
 
Регистрация: 23.04.2011
Сообщений: 42
По умолчанию

Да именно из-за такого удобства я и склонялся к СУБД, также и из-за готовых инструментов.
Я пытался еще юзать просто массивы для решения этой проблемы, но это был такой же бред как и TList.
Еще нарыл вот такую СУБД - ElevateDB. Встраивается в исполняемый файл при компиляции. Завтра посмотрю обе и выберу наиболее подходящую...
Freimaks вне форума Ответить с цитированием
Старый 17.04.2012, 22:06   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
а про какого провайдера речь?
Например IBProvider free OLE DB провайдер, бесплатный и удобный
Цитата:
ElevateDB
Так она ж платная, а FireBird бесплатная
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 17.04.2012 в 22:12.
Аватар вне форума Ответить с цитированием
Старый 17.04.2012, 22:09   #10
Прик
Форумчанин
 
Регистрация: 08.09.2010
Сообщений: 880
По умолчанию

Цитата:
Вот есть TClientDataSet, якобы встроенная СУБД, не требующая больше никаких телодвижений.
И правда, не требует, но и не поможет в нашем нелегком деле поиска дубликатов за разумное время.
Промышленные СУБД располагают многими возможностями для ускорения поиска в данных.
TClientDataSet - это всего лишь эрзац базы данных и в этом случае ничем не будет отличаться от TList/
Прик вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с большим количеством текста в String иTextbox Дмитрий999 Visual C++ 0 20.02.2012 20:07
Вывод данных в excel - массивом данных sergey113 Помощь студентам 4 22.08.2011 17:16
работа с большим объемом данных Ckif Microsoft Office Excel 1 14.09.2010 17:05
импорт из txt, работа с массивом данных, экспорт в txt Danara Microsoft Office Excel 4 31.03.2010 00:26
Метод для управления большим количеством данных eda Microsoft Office Excel 0 13.07.2009 10:50