将数字分配给字符C ++

时间:2016-05-25 03:41:07

标签: c++

我需要一种在C ++中为字母分配数字的方法,例如,'$'代表数字1.我显然需要能够从字符中获取类似函数的数字,例如getNumFromChar('$')将返回1而getNumFromChar('#')将返回2.在C ++中有一种简单快捷的方法吗?

8 个答案:

答案 0 :(得分:5)

最快的方法是编写一个256条目查找表,其中包含字符的ASCII索引中的映射值。这与isdigittolower的工作方式类似,例如:

int getNumFromChar(char c)
{
    static const int table[256] = {/* table entries */};

    return table[c & 0xff];
}

答案 1 :(得分:3)

如果您想自己分配值,请使用地图并将密钥存储到字母组合中。如果您可以使用映射到每个字母的预先指定的唯一值,并且只使用ASCII字符,则键入将它们转换为整数... ex)std :: static_cast< int>('$');

答案 2 :(得分:2)

创建一个由您的字符编入索引的向量std::vector<int> v(256,0);,最初所有数字都是零,您可以视为无效数字。最后为每个“编号”字符分配一些数字,例如v['$'] = 1; v['#'] = 2;使用一个事实,即字符实际上是从0到255的整数。

答案 3 :(得分:1)

正如评论中所指出的,您可以通过以下方式使用std::map

#include <iostream>
#include <map>
#include <cstring>

struct myComp
{
    bool operator()(const char* s1, const char* s2) const
    {
    return strcmp(s1, s2) < 0;
    }
};

int main()
{
    std::map<const char*, int, myComp> test;

    test["$"] = 1;
    test["#"] = 2;

    std::cout << "$ -> " << test["$"] <<"\n";
    std::cout << "# -> " << test["#"] <<"\n";

    return 0;
}

现场演示here

只有在最多存储256个值时,大多数其他答案才有效。但是,使用Maps,您可以存储任意数量的元素。

答案 4 :(得分:0)

很多人都在建议std::map<char,int>,这很好并且有效,但更快(?)这样做的方式没有依赖关系就是使用大量的switch语句

int getNumFromChar(char c){
    switch(c){
        case '$':
            return 1;
        case '#':
            return 2;
        //etc
    }
    return -1; //just in case of error, for style points
}

根据您对性能/内存使用的关注程度以及您必须编写的案例陈述的数量,这可能是也可能不是您想要的可行方式。我以为我会把它扔到那里,因为在写这篇文章时我不相信任何人。

编辑:此外,根据每个角色的使用频率,如果您在使用此功能之前知道整个映射,或者您更改了映射,std::map会更好,但我相信否则这会更快。

答案 5 :(得分:0)

你可以这样做:

#include <map>
#include <iostream>
#include <exception>

typedef std::map<char, int> easymap_type;

class EasyMap {
public:
    EasyMap() {}
    virtual ~EasyMap() {}

    void assign_int_to_char(const int& i, const char& c)
    {
        _map[c] = i;
    }

    int get_int_from_char(const char& c) const
    {
        easymap_type::const_iterator it = _map.find(c);
        if (it == _map.end())
        {
            std::cerr << "EasyMap Error: uninitialized key - '" << c << "'" << std::endl;
            throw std::exception();
        }
        return it->second;
    }

private:
    easymap_type _map;
};

int main()
{

    EasyMap ezmap;

    ezmap.assign_int_to_char(42, 'a');

    std::cout << "EasyMap[a] = " << ezmap.get_int_from_char('a') << std::endl;
    std::cout << "EasyMap[b] = " << ezmap.get_int_from_char('b') << std::endl;

    return 0;
}

我通过抛出异常处理了一个未初始化的密钥,但你可以采用不同的方式。

答案 6 :(得分:0)

如果您的编译器支持c ++ 11功能,您可以使用std::unordered_map作为容器来存储char,并使用std::unordered_map<char,double>加倍。 无序映射是一个关联容器,包含具有唯一键的键值对。元素的搜索,插入和删除具有平均的恒定时间复杂度。在您的问题中,char是键,double是您的值,char-double必须是存储在容器中的键值。

答案 7 :(得分:0)

已经有很多合理的答案......我更喜欢static_cast<int>('#')

总是必须有关于如何解决问题的最愚蠢无用的编译时模板想法。

我知道这很愚蠢,而且我并不擅长这种事情,但这是我在c ++ 11中的表现。别认真对待我。我只是不得不做一些蠢事。

#include <string>
#include <array>
#include <utility>
#include <iostream>

constexpr uint  kNbChars {3};

constexpr std::array<std::pair<char, int>, kNbChars> kCharToInt {
      std::make_pair('$', 1)
    , std::make_pair('#', 2)
    , std::make_pair('@', 3)
};

template <char c>
int getInt()
{
    for (auto pair : kCharToInt)
    {
        if (pair.first == c)
        { return pair.second; }
    }
    return -1;
}

int     main()
{
    std::cout << getInt<'#'>() << std::endl;
    std::cout << getInt<'g'>() << std::endl;
}

我认为你可以在c ++ 14中制作getInt()constexpr,但我可能错了,现在无法检查。

当然它真的没用,因为你必须在编译时知道这封信,但你可以解决这个问题,好吧,不要让getInt成为模板函数......