用C ++保存/存储/导出大对象

时间:2013-03-05 14:40:25

标签: c++ vector save export store

背景

我是一名新的c ++程序员,我正在尝试构建一个程序,该程序返回一个字符串,说明给定的十六进制颜色代码的颜色。整体功能是请求鼠标指针所在的像素的十六进制代码,并返回描述颜色的字符串(如#8B0000的“暗红色”)。 (我是色盲,这将是一个很大的帮助)

作为第一次尝试,我创建了一个.txt文件,其中包含换行符上的所有可能的颜色代码。毋庸置疑,该文件有16777216行,大134.2MB。我在互联网上搜索过,我发现在C ++中读取.txt文件的唯一方法是逐行,从头到尾。这将导致16777216次调用“getline()”字符串“Black”。这种方法暂时给我带来了“无望”的印记。

我想创建一个包含16777216(String color)实例的向量,并使用hex-to-int转换作为索引来定位正确的String。这个载体在构建或使用时也会变得非常大而且非常不方便。

问题:

我需要找到保存/保存大型对象以及我的c ++类的最佳方法(如果可能的话),这样我就可以导入该对象并立即使用它。

提前致谢。

6 个答案:

答案 0 :(得分:1)

A)您的文件包含超过16777216行,这意味着它包含的单词数量超过英语单词数量,可能还包括俄语,希腊语,中文和日语。

B)您需要将事物放入范围,然后对正确的范围进行二进制扫描。换句话说,将海军蓝的范围映射为范围内具有低值和高值的对象。

C)将所有范围放入一个大清单并对列表进行排序。

D)然后对任何特定颜色进行二元扫描,它将与正确的范围相交。

例如:

// Navy blue might be this range
Low  = RGB(0,0,170)
High = RGB(0,0,200)

// Light Red might be this range
Low  = RGB(240,0,0)
High = RGB(255,0,0)

我的意思是,如果您可以命名范围,为什么还要为每种颜色命名?

答案 1 :(得分:0)

OP发布:

  

我搜索了互联网,我发现在C ++中读取.txt文件的唯一方法是逐行,从头到尾。

这是不正确的。我不确定你正在使用哪些C ++文件读/写类,但如果你使用的那个不支持随机访问,那么找一个不同的。

如果您重新设置并使用fopen,则可以使用fseek转到文件中的特定位置。

如果将文件中的所有记录格式化为相同的长度,则可以轻松地将文件中的偏移量计算为recordnumber*recordlength(假设第一条记录为数字0)。

答案 2 :(得分:0)

感谢大卫和亚历克斯的讨论:)

单向查找值的简单解决方案

因此,我建议首先根据每个颜色值的四个MSB量化颜色空间。

val = ((hexval & 0xf00000) >> 12) | ((hexval & 0x00f000) >> 8) | ((hexval & 0x0000f0) >> 4)

同时创建一个std::vector<std::string>,其中包含4096个条目,您可以在其中读取颜色名称。

std::vector<std::string> names(4096);

//Read file and do for each line
names[val] = /*name for the value*/ 

//Lookup
const std::string& name = names[val];

对于双向查找,我仍然期待boost::bimap在从颜色值中查找名称时,可以将其配置为看起来像向量。并在找到与某个命名颜色匹配的颜色值时配置为哈希表。

答案 3 :(得分:0)

如果你想“保留”一个班级的对象,那么我建议去腌制它!这是library,我认为它适用于c ++

这些例程来自该库中的chooser.h,应该是有用的

// C++
DumpValToFile (const Val& thing_to_serialize,
           const string& output_filename,
           Serialization_e how_to_dump_the_data);

LoadValFromFile (const string& input_filename,
             Val& result,
             Serialization_e how_data_was_dumped);

我相信参数Val&amp;是你传递需要被捕捉的对象的地方

这些工具的作用是serialize一个对象,以便它可以轻松存储在硬盘上。

我从来没有亲自使用过这个工具,但是我在python中使用了类似的东西,所以我建议先用Python来试验腌制的东西。 Google“python pickle”获取更多信息。

答案 4 :(得分:-1)

我认为你只想实际'命名'非常少数可能的2 ^ 24 8位RGB值,所以std::map是你的朋友:< / p>

std::map<int, string> colors;

colors[0x000000] = "Black";
...
colors[0xFFFFFF] = "White";

您可以从这里开始使用HTML颜色名称:http://www.w3schools.com/html/html_colornames.asp

你还想写一个'findNearest'函数,(当然除非你实际上有1600万个不同的颜色名称)。您的findNearest会计算每种命名颜色与目标颜色之间RGB空间的距离。

答案 5 :(得分:-2)

我会在程序开始时将其全部读入std::map。然后使用该映射进行快速查找。如果读取文本文件需要很长时间,请考虑将其转换为某种二进制表示形式。解析每次查找的文本文件都会很慢。

如果您想要双向查找,即从值到名称,从名称到值。检查boost::multi_index http://www.boost.org/doc/libs/1_53_0/libs/multi_index/doc/index.htmlboost::bimap http://www.boost.org/doc/libs/1_53_0/libs/bimap/doc/html/index.html

我还会考虑使用boost :: serialization在两次运行之间存储和检索地图的数据。 http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/index.html