在简单的C中,如何制作相当于“地图”的?

时间:2015-04-27 01:58:37

标签: c dictionary data-structures

所以我试图从头开始制作一个程序(不包括库),我有一个非常难看的功能:

int parseUnsignedInt ( char * ch, unsigned int * ui )
{
/* Starting at character ch, reads the unsigned int into the
       variable ui, returns the number of characters read.
*/
    ui = 0; // unsigned integer into which the string representation is read 
    int m = 1; // multiplier
    int ncp = 0; // # of characters parsed
    while (*ch)
    {
        bool chid = false; // ch is a decimal
        for (int k = 0; k < decmapLength; ++k)
        {
            if (decmap[k].cval == *ch)
            {
                ui += decmap[k].ival * m;
                m *= 10;
                chid = true;
                break;
            }
        }
        if (!chid) break;
        ++ncp;
        ++ch;
    }
    return ncp;
}

部分丑陋源于我需要一种方法将char行动与int egers('0' - > 0,'1' - > 1,...联系起来。 。,'9' - &gt; 9)并制作数组或结构

typedef struct icpair
{
    char cval;
    int ival;
} icpair;

icpair decmap [10] = {{'0',0}, {'1',1}, {'2',2}, {'3',3}, {'4',4}, {'5',5}, {'6',6}, {'7',7}, {'8',8}, {'9',9}};
int decmapLength = sizeof(decmap)/sizeof(icpair);

为此目的。但是,查找一个值,如果它存在,则说明如果有更好的方法在纯C中执行此操作,可以压缩的难看的行数。我也希望这是可靠的,所以没有ASCII值减法'9'-'ch'。这在纯C中是否可行,如果可以,它是如何实现的?

2 个答案:

答案 0 :(得分:1)

C中的简单地图API可能如下所示:

Map * map_create(void);
void map_insert(Map * map, char key, int value);
int map_find(Map * map, char key);
void map_destroy(Map * map);

然后你就可以map_find(map, '0')来获取整数值,如果找不到它,可能会返回-1的语义。

根据您的需要,可以使用许多不同的数据结构来实现。如果您不关心维护订单,则哈希表可能是最合适的。例如,如果您确实需要基于密钥维护订单,那么二叉树可能是更好的主意(可能是红黑树)。

您可以修改API以获取密钥的void *,并将值稍微概括一下(在没有泛型的情况下,C缺少)。会增加复杂性,例如为哈希表提供哈希函数或为二叉树提供比较函数。

尽管如此,做*ch - '0'是安全的,并且可以正常工作。

答案 1 :(得分:0)

如果您想将任意 10个随机字符映射到0..9,您就不需要单独的结构元素ival - 自然为了&#39;已经正确索引正确的数字。因此,您可以使用一个长度为10个随机字符的char数组作为查找。

如果此数组中的字符连续递增1,则根本不需要该数组。在这种情况下,您可以减去第一个代码,测试结果是否在0到9之间,表示成功,否则拒绝该字符。

这适用于C,中的数字集,因为C的规范要求

  

在源和执行基本字符集中,上面列表中0之后的每个字符的值应比前一个值大1。 ( 5.2.1字符集 in   ISO/IEC 9899:201x Normative Draft 2011 (PDF)

因此,要获得任何数字的数值,character - '0' 总是为真。

作为旁注,未对范围A..Za..z定义。这意味着,如果您将'A'视为0,则无法保证'J'-'A' == 9。为此,您需要再次使用简单的查找字符数组。