0

バックグラウンド:

私は新しい C++ プログラマーで、指定された 16 進カラーコードの色を示す文字列を返すプログラムを構築しようとしています。全体的な機能は、マウスポインターが置かれているピクセルの 16 進コードを要求し、色を説明する文字列を返すことです (#8B0000 の「ダークレッド」など)。(私は色盲なので、とても助かります)

最初の試みとして、改行の可能なすべてのカラーコードを含む .txt ファイルを作成しました。言うまでもなく、ドキュメントには 16777216 行あり、134.2MB の大きさです。インターネットを検索したところ、C++ で .txt ファイルを読み取る唯一の方法は、最初から最後まで 1 行ずつ読むことであることがわかりました。その結果、文字列「Black」に対して「getline()」が 16777216 回呼び出されます。このアプローチは、今のところ私の「絶望的な」スタンプを付けました。

考え:

(文字列の色) の 16777216 個のインスタンスを含むベクターを作成し、16 進数から整数への変換を使用して、正しい文字列を見つけるためのインデックスとして使用したいと考えています。このベクトルも非常に大きくなり、構築または使用するのに非常に不便です。

問題:

オブジェクトをインポートしてすぐに使用できるように、大きなオブジェクトを 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

議論してくれてありがとう、デビッドとアレックス:)

一方向ルックアップ値から名前へのシンプルなソリューション

したがって、最初にすべての色値の 4 つの 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

投稿されたOP:

インターネットを検索したところ、C++ で .txt ファイルを読み取る唯一の方法は、最初から最後まで 1 行ずつ読むことであることがわかりました。

これは正しくありません。どの C++ ファイル読み取り/書き込みクラスを使用しているかはわかりませんが、使用しているクラスがランダム アクセスをサポートしていない場合は、別のクラスを見つけてください。

リセットして fopen を使用すると、fseek を使用してファイル内の特定の場所に移動できます。

ファイル内のすべてのレコードを同じ長さにフォーマットすると、ファイルへのオフセットを次のように簡単に計算できますrecordnumber*recordlength(最初のレコードが番号 0 であると仮定)。

于 2013-03-05T14:48:20.167 に答える
-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」関数を作成することもできます(もちろん、実際に色の名前が1,600万個ある場合を除きます)。findNearest名前付きの各色とターゲット色の間のRGB空間での距離を計算します。

于 2013-03-05T15:05:52.397 に答える
-2

std::mapプログラムの開始時にすべてを読みます。次に、そのマップを使用して高速検索を行います。テキストファイルの読み取りに時間がかかる場合は、バイナリ表現に変換することを検討してください。すべてのルックアップのテキストファイルの解析は遅くなります。

双方向のルックアップが必要な場合、つまり値から名前へ、名前から値へ。boost::multi_index http://www.boost.org/doc/libs/1_53_0/libs/multi_index/doc/index.html またはhttp://www.boost.org/doc/libs/1_53_0/libs/bimap/doc/htmlを確認してくださいboost::bimap /index.html

また、boost :: serializationを使用して、実行の合間にマップのデータを保存および取得することも検討します。 http://www.boost.org/doc/libs/1_53_0/libs/serialization/doc/index.html

于 2013-03-05T14:58:11.317 に答える