我需要一种在C ++中为字母分配数字的方法,例如,'$'
代表数字1.我显然需要能够从字符中获取类似函数的数字,例如getNumFromChar('$')
将返回1而getNumFromChar('#')
将返回2.在C ++中有一种简单快捷的方法吗?
答案 0 :(得分:5)
最快的方法是编写一个256条目查找表,其中包含字符的ASCII索引中的映射值。这与isdigit
和tolower
的工作方式类似,例如:
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成为模板函数......