2011-10-21 2 views
2

Cでこのようなマップをどのように表現できますか?constを文字列に変換するための慣用句C

{ 
{1, "One"}, 
{1000, "One thousand"}, 
{1000000, "One million"} 
} 

キーはint型で、大きなint型にすることができます。値は定数文字列であり、コンパイル時に認識されます。

マップには20または30の要素が含まれます。

私はこの関数を記述します。

const char* numbers(const int i) 
{ 
    switch(i) { 
     case  1: return "One"; 
     case 1000: return "One thousand"; 
     case 1000000: return "One million"; 
     default: return ""; 
    } 
} 

はそれをやって、任意の適切な(慣用)方法は何ですか?

+1

これは、ハッシュテーブルのためのものです。 Cでは、他の高水準言語とは異なり、言語はそのような機能を提供しておらず、あなた自身のものを考え出す必要があります。 –

+1

@BlagovestBuyukliev:整数をハッシュするのはやや珍しいことです。数字キーの場合、バイナリ検索が一般的です。 (もちろん、あなたは* can *ですが、積分データでテストされるハッシュ関数はあまりありません)。 –

+0

@Dietrich:はい、確かに、私はより一般的な意味で話していました。 –

答えて

3

スイッチを使用するのは完全に熟語Cです。キー/値のデータをプログラムロジックから分離するかどうかは、別のスタイルの考慮事項(ほとんどすべての言語に適用されます)があります。

const struct { int key; const char *value; };の配列を使用できますが、線形検索、バイナリ検索、完全ハッシュなどの使用を心配することになります。スイッチを使用すると、コンパイラはそれを手から取り除きます。

このプロジェクトの他のものに使用する何らかの種類の結合コンテナ(ツリーまたはハッシュマップ)がある場合は、それを使用できますが、30項目のコレクションの場合はそれを書く価値はありません。あなたが行ったよう

3

typedef struct { 
    long long key; 
    char *val; 
} Item; 

const Item mydict[] = { 
    {1, "One"}, 
    {1000, "One thousand"}, 
    {1000000, "One million"} 
}; 

私は運動としてnumbers()関数の本体を残します。

Steve Jessopで提案されている代替ソリューションも完全に有効です。

+0

これはどのように答えですか?あなたは基本的にOPの質問を完全に無視し、運動として残しました!! – Shahbaz

+0

@Shahbaz - 次に、downvoteを考慮する必要があるかもしれません。 – mouviciel

2

すべてが静的に既知であるならば、私はこのようなものとなるだろう:

char strings[][] = {"One", "One thousand", "One million", /* whatever */}; 
int map[] = {1, 1000, 1000000}; 

const char *numbers(const int i) 
{ 
    position = search(map, i);// if the array is too small, just linear search 
           // if it is big, you can binary search 
           // if there is a relation use a formula 
           // although a formula is not extendable. 
           // In this case, it is log(i) in base 1000. 
    return strings[position]; 
} 

この方法は、非静的データのために拡張することができます。 stringsアレイを正しく記入し、mapをソートしたままにしてください。

注:明らかに、十分なエラーチェックなどを追加する必要があります。例えば、searchiを見つけられなかった場合です。

+0

確かに文字列を返すことを意味しますか?私は編集しただろうが、変更が短すぎた。 – tinman

+0

@tinman、ああ、もちろん。 – Shahbaz

1

これは1つの解決策です。

を基本的にソートのキーと値のペアの配列を作成し、bsearch-function(バイナリ検索を実行)を使用して正しい値をすばやく見つけます。より便利な検索を行うために、独自のバイナリ検索を実装することは理にかなっています。

#include <stdlib.h> 
#include <stdio.h> 

typedef struct mapping 
{ 
    int key; 
    char* value; 
} Mapping; 

int mappingCompare(const void* a, const void* b) 
{ 
    const Mapping* first = (const Mapping*)a; 
    const Mapping* second = (const Mapping*)b; 
    return second->key - first->key; 
} 

int main() 
{ 
    Mapping map[3]; 
    Mapping search; 
    Mapping* result; 
    map[0].key = 1; 
    map[0].value = "One"; 
    map[1].key = 1000; 
    map[1].value = "One thousand"; 
    map[2].key = 1000000; 
    map[2].value = "One million"; 

    //qsort is only needed if the map is not already in order 
    qsort(map, 3, sizeof(Mapping), mappingCompare); 

    search.key = 1000; 
    result = (Mapping*)bsearch(&search, map, 3, sizeof(Mapping), mappingCompare); 
    printf("value for key 1000 is %s\n", result->value); 
}