背景
我是一名新的c ++程序员,我正在尝试构建一个程序,该程序返回一个字符串,说明给定的十六进制颜色代码的颜色。整体功能是请求鼠标指针所在的像素的十六进制代码,并返回描述颜色的字符串(如#8B0000的“暗红色”)。 (我是色盲,这将是一个很大的帮助)
作为第一次尝试,我创建了一个.txt文件,其中包含换行符上的所有可能的颜色代码。毋庸置疑,该文件有16777216行,大134.2MB。我在互联网上搜索过,我发现在C ++中读取.txt文件的唯一方法是逐行,从头到尾。这将导致16777216次调用“getline()”字符串“Black”。这种方法暂时给我带来了“无望”的印记。
观
我想创建一个包含16777216(String color)实例的向量,并使用hex-to-int转换作为索引来定位正确的String。这个载体在构建或使用时也会变得非常大而且非常不方便。
问题:
我需要找到保存/保存大型对象以及我的c ++类的最佳方法(如果可能的话),这样我就可以导入该对象并立即使用它。
提前致谢。
答案 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.html
或boost::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