[英]Can we make a map in C++, with the value as a function of key?
In C++ STL, the map is used to map the key to a value. 在C ++ STL中,映射用于将键映射到值。 I want to know whether we can do this mapping based on some function say
我想知道我们是否可以根据一些功能说来做这种映射
map< int, string > M;
map <int,string> M;
and value=binary_representation(key) ?和value = binary_representation(key)?
You can insert arbitrary ( key , value ) pairs into a std::map
so you can certainly insert ( x i , f ( x i )) pairs for a function f and any x 1 , …, x n you like, provided that the types match. 您可以在
std::map
插入任意( key , value )对,因此您当然可以为函数f和任意x 1 ,…, x n插入( x i , f ( x i ))对,只要类型匹配。
The straight-forward way to do this might be to use a for
loop. 直接执行此操作的方法可能是使用
for
循环。
for (const auto& k : keys)
mapping[k] = f(k);
Here is a complete example: 这是一个完整的示例:
#include <climits>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
namespace /* anonymous */
{
std::string
my_function(const int n)
{
const auto size = static_cast<int>(CHAR_BIT * sizeof(int));
std::string bits {};
for (auto i = 0; i < size; ++i)
{
const auto bit = (n >> (size - i - 1)) & 1;
bits += (bit ? '1' : '0');
}
return bits;
}
}
int
main()
{
std::map<int, std::string> reprs {};
for (auto k = -3; k < 10; ++k)
reprs[k] = my_function(k);
for (const auto& kv : reprs)
std::cout << std::setw(4) << kv.first << " => " << kv.second << '\n';
}
Possible output: 可能的输出:
-3 => 11111111111111111111111111111101
-2 => 11111111111111111111111111111110
-1 => 11111111111111111111111111111111
0 => 00000000000000000000000000000000
1 => 00000000000000000000000000000001
2 => 00000000000000000000000000000010
3 => 00000000000000000000000000000011
4 => 00000000000000000000000000000100
5 => 00000000000000000000000000000101
6 => 00000000000000000000000000000110
7 => 00000000000000000000000000000111
8 => 00000000000000000000000000001000
9 => 00000000000000000000000000001001
If you want to follow the advice of favoring algorithms over raw loops, you could use std::transform
together with a std::insert_iterator
to do the trick. 如果您想遵循
std::insert_iterator
于原始循环的算法的建议,则可以将std::transform
与std::insert_iterator
一起使用来完成此任务。
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <string>
#include <utility>
#include <vector>
namespace /* anonymous */
{
std::string
my_function(int); // as above
}
int
main()
{
std::vector<int> keys(13);
std::iota(keys.begin(), keys.end(), -3);
std::map<int, std::string> reprs {};
const auto generator = [](const int n){
return std::make_pair(n, my_function(n));
};
std::transform(keys.cbegin(), keys.cend(),
std::inserter(reprs, reprs.begin()),
generator);
for (const auto& kv : reprs)
std::cout << std::setw(4) << kv.first << " => " << kv.second << '\n';
}
However, I'm not sure if the use of iterators and algorithms really helps the readability of the code in this simple case. 但是,在这种简单情况下,我不确定使用迭代器和算法是否真的有助于代码的可读性。 The use of the
keys
vector is a bit of an abomination here. 这里使用
keys
向量有点令人讨厌。 If you have Boost, you could replace it by a boost::counting_iterator
. 如果您拥有Boost,可以将其替换为
boost::counting_iterator
。
You could do, but it would be completely pointless. 您可以这样做,但这将完全没有意义。 It would just be an inferior
std::set<int>
that doesn't properly guarantee the invariant and consumes a higher memory usage and runtime for absolutely no benefit whatsoever (unless you really wanted a cache). 它只是劣等的
std::set<int>
,不能正确地保证不变性,并且消耗更高的内存使用量和运行时间,而丝毫没有任何好处(除非您确实想要缓存)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.