0

背景:

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

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

主意:

我想创建一个包含 16777216 个 (String colour) 实例的向量,并使用十六进制到整数的转换作为索引来定位正确的字符串。这个向量也会变得非常大并且非常不方便构建或使用。

问题:

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

提前致谢。

4

6 回答 6

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)

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

于 2013-03-05T16:23:00.690 回答
0

OP发布:

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

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

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

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

于 2013-03-05T14:48:20.167 回答
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它可以配置为在从颜色值中查找名称时看起来像一个向量。并在找到与某个命名颜色匹配的颜色值时配置为哈希表。

于 2013-03-05T16:20:40.573 回答
0

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

这些例程来自该库中的选择器.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& 是您传递需要腌制的对象的地方

这些工具所做的是将对象序列化,以便可以轻松地将其存储在硬盘上。

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

于 2013-05-16T17:35:22.253 回答
-1

我认为您实际上只想“命名”少数可能的 2^24 8 位 RGB 值,std::map您的朋友也是:

std::map<int, string> colors;

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

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

您还需要编写一个“findNearest”函数(当然,除非您实际上有 1600 万个不同的颜色名称)。您findNearest将计算每个命名颜色和目标颜色之间在 RGB 空间中的距离。

于 2013-03-05T15:05:52.397 回答
-2

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

如果您想要双向查找,即从值到名称以及从名称到值。检查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

于 2013-03-05T14:58:11.317 回答