私はいくつかのc ++コードをcに移植しています。 cのstd :: mapの実行可能な同等物は何ですか?私はcに同等のものがないことを知っています。
これは私が使用することを考えているものです:
C++の場合:
std::map< uint, sTexture > m_Textures;
Cの場合:
typedef struct
{
uint* intKey;
sTexture* textureValue;
} sTMTextureMap;
それは実行可能ですか、それともマップを単純化しすぎていますか?目的が得られなかった場合に備えて、テクスチャマップです。
多くのC実装は、tsearch(3)またはhsearch(3)をサポートしています。 tsearch(3)は二分木であり、コンパレータコールバックを提供できます。これは、std :: mapに到達するのとほぼ同じだと思います。
これがc99のサンプルコードです
#include <search.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct
{
int key;
char* value;
} intStrMap;
int compar(const void *l, const void *r)
{
const intStrMap *lm = l;
const intStrMap *lr = r;
return lm->key - lr->key;
}
int main(int argc, char **argv)
{
void *root = 0;
intStrMap *a = malloc(sizeof(intStrMap));
a->key = 2;
a->value = strdup("two");
tsearch(a, &root, compar); /* insert */
intStrMap *find_a = malloc(sizeof(intStrMap));
find_a->key = 2;
void *r = tfind(find_a, &root, compar); /* read */
printf("%s", (*(intStrMap**)r)->value);
return 0;
}
std::map
の周りにCインターフェイスをラップしてみませんか?つまり、独自のモジュールでいくつかのC++関数を記述します。
typedef std::map<int, char*> Map;
extern "C" {
void* map_create() {
return reinterpret_cast<void*> (new Map);
}
void map_put(void* map, int k, char* v) {
Map* m = reinterpret_cast<Map*> (map);
m->insert(std::pair<int, char*>(k, v));
}
// etc...
} // extern "C"
そして、Cアプリにリンクします。
それは確かに1つの可能な実装です。インデックス作成をどのように実装するか、およびパフォーマンスにどのような影響があるかを検討することをお勧めします。たとえば、intKeyリストをキーのソートされたリストにすることができます。キーの検索はO(log N)時間ですが、新しいアイテムの挿入はO(N)になります。
これをツリー(std :: mapなど)として実装すると、O(log N)の挿入とルックアップが可能になります。
もう1つの方法は、ハッシュテーブルとして実装することです。これは、優れたハッシュ関数と十分にまばらなintKey配列を前提として、実行時のパフォーマンスが向上します。
私はCでマップを実装しようとしました、それはvoidに基づいています*
https://github.com/davinash/cstl
作業中ですが、地図は完成です。
https://github.com/davinash/cstl/blob/master/src/c_map.c
赤黒木をベースに書かれています。
好きなように実装できます。リンクリストアプローチを使用する場合、挿入はO(1)になりますが、取得と削除はO(n)になります)。赤黒木のようなより複雑なものを使用する場合は、はるかに優れた平均パフォーマンスが得られます。
自分で実装する場合は、リンクリストがおそらく最も簡単です。そうでない場合は、適切にライセンスされた赤黒または他のタイプのツリーをインターネットから取得するのが最善のオプションです。独自の赤黒木を実装することはお勧めしません...私はこれを実行したので、二度と実行したくないと思います。
そして、あなたが尋ねなかった質問に答えるために:多分あなたはC++からCへの移植が本当にあなたが望むすべての利益を提供するかどうかを再検討するべきです。確かに必要な場合もありますが、それほど多くはありません。
Cには、マップに類似した機能を提供する標準ライブラリはありません。キーを介した要素へのアクセスをサポートする何らかの形式のコンテナを使用して、独自のマップのような機能を実装する必要があります。
男dbopen
ファイル引数としてNULLを指定すると、キー/値データのメモリ内のみのコンテナになります。
同様のキー/値機能を備えたさまざまなBerkeleyデータベースライブラリインターフェイスもあります(man dbm、SleepycatからBerkeleyDBをチェックアウト、いくつかの検索を試すなど)。