Вектор массивов. Чтение/запись из/в файл.
От: Cheat  
Дата: 23.06.11 15:31
Оценка:
Добрый день!

Есть задачка из области двоичных функций, точнее расчет некоторых характеристик.
В массив длинны, скажем 7, заносятся числовые значения. Далее у этого массива есть своя характеристика (сколько раз он встречается в веторе).
Здесь первый вопрос — лучше сделать структуру в которой будет массив и это значение или сделать массив длины 8 и в последней ячейке хранить это значение.

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

Как это лучше реализовать? Язык c++
Re: Вектор массивов. Чтение/запись из/в файл.
От: __UNIX_hokum  
Дата: 24.06.11 04:11
Оценка: 2 (1) :)
C>Здесь первый вопрос — лучше сделать структуру в которой будет массив и это значение или сделать массив длины 8 и в последней ячейке хранить это значение.
Можно использовать boost::fusion::vector, он позволяет хранить разнотиповые значения. Что-то вроде

#include <boost/fusion/include/vector.hpp>
typedef double data_t;
typedef unsigned short freqency;
typedef boost::fusion::vector<data_t,data_t,data_t,data_t,data_t,data_t,data_t,frequency> container;
container c(1.2,2.3,3.4,4.5,5.6,6.7,7.8,100);


C>Их я хочу запихнуть в вектор. И этот вектор нужно записывать в файл и затем (уже в другой программе) считывать.

Здесь могу посоветовать вручную наваять генератор на boost::spirit::karma, и парсер на boost::spirit::qi; С boost-овской сериализацией я не работал, поэтому её советовать не буду.
Re: Вектор массивов. Чтение/запись из/в файл.
От: jazzer Россия Skype: enerjazzer
Дата: 24.06.11 04:22
Оценка: 2 (1)
Здравствуйте, Cheat, Вы писали:

C>Добрый день!


C>Есть задачка из области двоичных функций, точнее расчет некоторых характеристик.

C>В массив длинны, скажем 7, заносятся числовые значения. Далее у этого массива есть своя характеристика (сколько раз он встречается в веторе).
C>Здесь первый вопрос — лучше сделать структуру в которой будет массив и это значение или сделать массив длины 8 и в последней ячейке хранить это значение.

C>И вот таких массивов будет около 30к (в последствии больше и они будут длиннее).

C>Их я хочу запихнуть в вектор. И этот вектор нужно записывать в файл и затем (уже в другой программе) считывать.

C>Как это лучше реализовать? Язык c++


Если все происходит на одной и той же машине и компилируется одинаково в смысле размеров и выравниваний, то делай свою структуру POD (неважно, как ты решишь вопрос с последней ячейкой-счетчиком, главное, чтоб массив был фиксированной длины) и потом скидывай память вектора целиком на диск одним вызовом write.
Когда будешь читать, посмотри на размер файла, определи длину из него, отресайзь вектор и потом read всего файла по адресу его первого элемента.
Это — самое простое.

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

Если ты можешь все представить в виде двумерного массива, то все еще проще — читай в буфер и юзай boost::MultiArray. В этом случае оно все у тебя может быть переменного размера, только зарезервируй в начале файла место под заголовок, в которм будешь хранить размерность.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 04:55
Оценка: 2 (1)
Здравствуйте, Cheat, Вы писали:


C>Есть задачка из области двоичных функций, точнее расчет некоторых характеристик.

C>В массив длинны, скажем 7, заносятся числовые значения. Далее у этого массива есть своя характеристика (сколько раз он встречается в веторе).
C>Здесь первый вопрос — лучше сделать структуру в которой будет массив и это значение или сделать массив длины 8 и в последней ячейке хранить это значение.

Лучше структуру из массива и поля.
Типа так:
struct DataWithWeight {
    enum { DataCount = 7 };
    int Data[DataCount];
    int Weight;
};


C>И вот таких массивов будет около 30к (в последствии больше и они будут длиннее).

Тут весь вопрос в том, насколько длиннее. Да, 30к -- это число байт, чисел или структур?
Да, и ещё вопрос, прога 32-битная или 64-х?

C>Их я хочу запихнуть в вектор.

В любом случае пока можно сделать std::vector<DataWithWeight>.

Но, если речь идёт о int, или, пуще того, о double + 30к структур, то sizeof структуры будет где-то в четверть килобайта.
То есть 30К структур потребуют 7 с половиной метров памяти подряд. Это фигня, но если задачка подрастёт на пару порядков, и надо будет уже 700 метров подряд, то на 32-й ОС могут быть проблемы...

C>И этот вектор нужно записывать в файл и затем (уже в другой программе) считывать.

Нужно ли сделать так, чтобы человек мог читать эти файлы?
Если надо, то пиши в текстовый файл.
Например так:
template<typename TOStream>
TOStream& operator << (TOStream& dst, const DataWithWeight& data)
{
    for( int i = 0; i < DataWithWeight::DataCount; i++) {
        dst << data.Data[i];
    }
    dst << data.Weight << std::endl;
}
Ну и читалку аналогичную.
И потом в цикле по большому массиву.

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

То есть что-то типа (я не знаю, через что ты работаешь с файлами, поэтому файл будет условный)
void writeData( CFile& file, const std::vector<DataWithWeight>& data)
{
    int size = data.size();
    file.Write( &size, sizeof( size ) );
    if( size > 0 ) {
        file.Write( &data[0], sizeof( data[0] ) * size );
    }
}

//  Возвращает true, если удалось считать без ошибок.
bool readData( CFile& file, const std::vector<DataWithWeight> data)
{
    int size = data.size();
    if( file.Read( &size, sizeof( size ) ) != sizeof( size ) || size < 0 ) 
        return false;
    if( size == 0 )
        return true;
    data.set_size( size );
    return file.Read( &data[0], sizeof( data[0] ) * size ) == sizeof( data[0] ) * size;
}

C>Как это лучше реализовать? Язык c++
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Вектор массивов. Чтение/запись из/в файл.
От: Cheat  
Дата: 24.06.11 06:04
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Cheat, Вы писали:



C>>Есть задачка из области двоичных функций, точнее расчет некоторых характеристик.

C>>В массив длинны, скажем 7, заносятся числовые значения. Далее у этого массива есть своя характеристика (сколько раз он встречается в веторе).
C>>Здесь первый вопрос — лучше сделать структуру в которой будет массив и это значение или сделать массив длины 8 и в последней ячейке хранить это значение.

E>Лучше структуру из массива и поля.

E>Типа так:
struct DataWithWeight {
E>    enum { DataCount = 7 };
E>    int Data[DataCount];
E>    int Weight;
E>};


C>>И вот таких массивов будет около 30к (в последствии больше и они будут длиннее).

E>Тут весь вопрос в том, насколько длиннее. Да, 30к -- это число байт, чисел или структур?
E>Да, и ещё вопрос, прога 32-битная или 64-х?

Максимальная длинна 11, больше не нужно
30 тысяч массивов длинны 7, но дальше
Прога 32 битная

C>>Их я хочу запихнуть в вектор.

E>В любом случае пока можно сделать std::vector<DataWithWeight>.

E>Но, если речь идёт о int, или, пуще того, о double + 30к структур, то sizeof структуры будет где-то в четверть килобайта.

E>То есть 30К структур потребуют 7 с половиной метров памяти подряд. Это фигня, но если задачка подрастёт на пару порядков, и надо будет уже 700 метров подряд, то на 32-й ОС могут быть проблемы...

Максимальное количетсово 4294967296, которое, видимо, сделать не получится
Тогда придется на 65 тысячах остановится


C>>И этот вектор нужно записывать в файл и затем (уже в другой программе) считывать.

E>Нужно ли сделать так, чтобы человек мог читать эти файлы?

Нет, я так подумал, можно все алгоритмы перехода в одну программу запихнуть, а уже использованные массивы уничтожать

E>Если надо, то пиши в текстовый файл.

E>Например так:
E>
template<typename TOStream>
E>TOStream& operator << (TOStream& dst, const DataWithWeight& data)
E>{
E>    for( int i = 0; i < DataWithWeight::DataCount; i++) {
E>        dst << data.Data[i];
E>    }
E>    dst << data.Weight << std::endl;
E>}
Ну и читалку аналогичную.

E>И потом в цикле по большому массиву.

E>А если чтение файла человеком не требуется, то можно просто записать длину массива, а потом все данные единым блоком. Только для этого надо, чтобы структура DataWithWieght была бы POD типом.


E>То есть что-то типа (я не знаю, через что ты работаешь с файлами, поэтому файл будет условный)
void writeData( CFile& file, const std::vector<DataWithWeight>& data)
E>{
E>    int size = data.size();
E>    file.Write( &size, sizeof( size ) );
E>    if( size > 0 ) {
E>        file.Write( &data[0], sizeof( data[0] ) * size );
E>    }
E>}

E>//  Возвращает true, если удалось считать без ошибок.
E>bool readData( CFile& file, const std::vector<DataWithWeight> data)
E>{
E>    int size = data.size();
E>    if( file.Read( &size, sizeof( size ) ) != sizeof( size ) || size < 0 ) 
E>        return false;
E>    if( size == 0 )
E>        return true;
E>    data.set_size( size );
E>    return file.Read( &data[0], sizeof( data[0] ) * size ) == sizeof( data[0] ) * size;
E>}

C>>Как это лучше реализовать? Язык c++
Re[2]: Вектор массивов. Чтение/запись из/в файл.
От: Cheat  
Дата: 24.06.11 06:08
Оценка:
Ах да, чуть не забыл, вектор приоритетней использовать т.к. те массивы которые встречаются несколько раз, нужно оставлять в одном экземпляре
Re[2]: Вектор массивов. Чтение/запись из/в файл.
От: gegMOPO4  
Дата: 24.06.11 11:33
Оценка: :)
Здравствуйте, Erop, Вы писали:
E>
template<typename TOStream>
E>TOStream& operator << (TOStream& dst, const DataWithWeight& data)
E>{
E>    for( int i = 0; i < DataWithWeight::DataCount; i++) {
E>        dst << data.Data[i];
E>    }
E>    dst << data.Weight << std::endl;
E>}


Но-но-но, разделители.

E>То есть что-то типа (я не знаю, через что ты работаешь с файлами, поэтому файл будет условный) [c]void writeData( CFile& file, const std::vector<DataWithWeight>& data)

E>{
E> int size = data.size();
E> file.Write( &size, sizeof( size ) );
E> if( size > 0 ) {
E> file.Write( &data[0], sizeof( data[0] ) * size );
E> }
E>}

А здесь разумнее сразу выделить writeInt, writeDouble (и аналогичные read*) и писать/читать по примитивным типам. Если потом понадобиться портировать на другую платформу, другой компилятор, другой язык, другую версию программы или собранную с другими опциями — проще будет переписать переносимее. А контроль только по размеру структуры недостаточен.
Re[3]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 13:58
Оценка:
Здравствуйте, Cheat, Вы писали:

C>Максимальное количетсово 4294967296, которое, видимо, сделать не получится

C>Тогда придется на 65 тысячах остановится

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

Вектор налагает доп. требования. Он должен хранить свои данные единым куском в памяти. Обычно в 32-й системе не получается иметь куски сильно больше 0.5 гига.
но есть, всякие штуки, вроде rope, которы умеют больше.
В любом случае, если данных так много, то программу стоит проектировать как-то иначе.
Так что лучше бы РЕАЛЬНО оценить объём твоей задачи. Как ты понимаешь, 4294967296 и 30 000 довольно сильно отличаются по порядку величины
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 13:58
Оценка:
Здравствуйте, Cheat, Вы писали:

C>Ах да, чуть не забыл, вектор приоритетней использовать т.к. те массивы которые встречаются несколько раз, нужно оставлять в одном экземпляре


Это меято я не понял
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 14:27
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Но-но-но, разделители.

зачем? Это же передача данных между овердеями?

MOP>А здесь разумнее сразу выделить writeInt, writeDouble (и аналогичные read*) и писать/читать по примитивным типам. Если потом понадобиться портировать на другую платформу, другой компилятор, другой язык, другую версию программы или собранную с другими опциями — проще будет переписать переносимее. А контроль только по размеру структуры недостаточен.


Ерунда это всё. Лишняя трата времени, как программиста, так и компика.
Нужен совместимый формат, контролируемый формат -- пиши в текст...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Вектор массивов. Чтение/запись из/в файл.
От: Cheat  
Дата: 24.06.11 14:46
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Cheat, Вы писали:


C>>Максимальное количетсово 4294967296, которое, видимо, сделать не получится

C>>Тогда придется на 65 тысячах остановится

E>Э-э-э, ты должен, как бы не забывать, что твои творческие планы ограничены объёмом используемой памяти


E>Вектор налагает доп. требования. Он должен хранить свои данные единым куском в памяти. Обычно в 32-й системе не получается иметь куски сильно больше 0.5 гига.

E>но есть, всякие штуки, вроде rope, которы умеют больше.
E>В любом случае, если данных так много, то программу стоит проектировать как-то иначе.
E>Так что лучше бы РЕАЛЬНО оценить объём твоей задачи. Как ты понимаешь, 4294967296 и 30 000 довольно сильно отличаются по порядку величины

В задаче использутся рекуррентная формула и поэтому такой разброс значений.
При переходе от параметров (2,2,2) к (3,2,2) получается около 30000 таких структур
А вот при переходе от (3,2,2) к (4,2,2) уже чуть более миллиарда структур длинны 11 + вес + значение длинны, это все int
Вот я этот вектор построить и не могу, гдето на гигабайте памяти выбивает программу
Re[5]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 14:59
Оценка:
Здравствуйте, Cheat, Вы писали:

C>А вот при переходе от (3,2,2) к (4,2,2) уже чуть более миллиарда структур длинны 11 + вес + значение длинны, это все int

C>Вот я этот вектор построить и не могу, гдето на гигабайте памяти выбивает программу

А может таки лучше попробовать какой-то более другой алгоритм? И какой-то более другой язык, за одно?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Вектор массивов. Чтение/запись из/в файл.
От: gegMOPO4  
Дата: 24.06.11 15:42
Оценка: 12 (1)
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, gegMOPO4, Вы писали:
MOP>>Но-но-но, разделители.
E>зачем? Это же передача данных между овердеями?

Я всего лишь намекаю на то, что числа хорошо бы разделять пробелами. Если мы, конечно, планируем потом их прочитать обратно.

MOP>>А здесь разумнее сразу выделить writeInt, writeDouble (и аналогичные read*) и писать/читать по примитивным типам. Если потом понадобиться портировать на другую платформу, другой компилятор, другой язык, другую версию программы или собранную с другими опциями — проще будет переписать переносимее. А контроль только по размеру структуры недостаточен.

E>Ерунда это всё. Лишняя трата времени, как программиста, так и компика.
E>Нужен совместимый формат, контролируемый формат -- пиши в текст...

Всё так. Но некоторые испытывают необъяснимое недоверие к текстовым форматам.
Re[6]: Вектор массивов. Чтение/запись из/в файл.
От: Cheat  
Дата: 24.06.11 16:22
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Cheat, Вы писали:


C>>А вот при переходе от (3,2,2) к (4,2,2) уже чуть более миллиарда структур длинны 11 + вес + значение длинны, это все int

C>>Вот я этот вектор построить и не могу, гдето на гигабайте памяти выбивает программу

E>А может таки лучше попробовать какой-то более другой алгоритм? И какой-то более другой язык, за одно?


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

А язык, помимо си, явы и паскаля я в языках не силен
Re[5]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 16:42
Оценка:
Здравствуйте, gegMOPO4, Вы писали:

MOP>Я всего лишь намекаю на то, что числа хорошо бы разделять пробелами. Если мы, конечно, планируем потом их прочитать обратно.


А, это да Спасибо.

MOP>Всё так. Но некоторые испытывают необъяснимое недоверие к текстовым форматам.

Ну так надо работать над собой и искоренять суеверия, замещая их умными мыслями
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[7]: Вектор массивов. Чтение/запись из/в файл.
От: Erop Россия  
Дата: 24.06.11 16:44
Оценка: 3 (1)
Здравствуйте, Cheat, Вы писали:

C>К сожалению, другой алоритм не получится, только таким "тупым" перебором в лоб. Целью является проверить другую формулу приближенного подсчета. Хотя полученных результатов может хватить, но всеже наиболее интересно было бы проверить при таких больших значениях.


А зачем тогда ограничиваться 32-битными приложениями? В 64-битах попроще многое будет.

C>А язык, помимо си, явы и паскаля я в языках не силен

Ну финкциональщину какую-нибудь посмотри. Или на маткад, например, какой...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.