25

私はいくつかのc++コードをcに移植しています。cのstd::mapに相当する実行可能なものは何ですか?私はcに同等のものがないことを知っています。

これは私が使用することを考えているものです:

C ++の場合:

std::map< uint, sTexture > m_Textures;

cの場合:

typedef struct
{
  uint* intKey;
  sTexture* textureValue;
} sTMTextureMap;

それは実行可能ですか、それともマップを単純化しすぎていますか?目的が得られなかった場合に備えて、テクスチャマップです。

4

7 に答える 7

34

多くの 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;
}
于 2009-03-15T02:18:39.873 に答える
18

C インターフェースをラップしてみませんstd::mapか? つまり、独自のモジュールにいくつかの 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 アプリにリンクします。

于 2010-10-01T15:19:04.607 に答える
5

それは確かに可能な実装の 1 つです。インデックス作成の実装方法と、パフォーマンスへの影響を検討する必要がある場合があります。たとえば、intKey リストをキーのソート済みリストにすることができます。キーを検索するのに O(log N) 時間かかりますが、新しいアイテムを挿入するのに O(N) かかります。

それをツリー (std::map など) として実装すると、O(log N) の挿入とルックアップが可能になります。

もう 1 つの方法は、ハッシュ テーブルとして実装することです。これは、適切なハッシュ関数と十分にスパースな intKey 配列を前提として、実行時のパフォーマンスが向上します。

于 2009-03-15T01:30:39.800 に答える
3

どのように選択しても実装できます。リンク リスト アプローチを使用する場合、挿入は O(1) になりますが、取得と削除は O(n) になります。赤黒木などのより複雑なものを使用すると、平均的なパフォーマンスが大幅に向上します。

自分で実装する場合は、リンクされたリストがおそらく最も簡単です。それ以外の場合は、適切にライセンスされた赤黒またはその他の種類のツリーをインターネットから取得するのが最適なオプションです。独自の赤黒ツリーを実装することはお勧めしません... 私はこれを実行しましたが、二度と実行したくありません。

そして、あなたが聞いていなかった質問に答えるために、おそらく、C++ から C への移植が本当にあなたが望んでいたすべての利点を提供するかどうかを再検討する必要があります. 確かにそれが必要な状況はありますが、多くはありません。

于 2009-03-15T02:08:50.910 に答える
3

Cでマップを実装しようとしましたが、void *に基づいています

https://github.com/davinash/cstl

工事中ですが、地図は完成しています。

https://github.com/davinash/cstl/blob/master/src/c_map.c

赤黒木をもとに書かれています。

于 2011-04-12T13:41:01.567 に答える
0

マップに類似した機能を提供するCの標準ライブラリはありません。キーを介した要素へのアクセスをサポートする何らかの形式のコンテナを使用して、独自のマップのような機能を実装する必要があります。

于 2009-03-15T01:13:49.593 に答える
0

男 dbopen

ファイル引数として NULL を指定すると、キー/値データのメモリ内専用コンテナーになります。

同様のキー/値機能を備えたさまざまな Berkeley データベース ライブラリ インターフェイスもあります (man dbm、Sleepycat から BerkeleyDB をチェックアウト、検索を試すなど)。

于 2009-03-15T01:46:49.590 に答える