我想将地图中存储的所有单词更改为小写。有了lambda函数和变换,我该怎么做?
std::map <string, int> M;
std::map<string, int> M1;
std::transform(M.begin(), M.end(), M1.begin(),
[](pair<const string, int> const & p) { ::tolower(p.first); });
答案 0 :(得分:2)
您无法在#include <iostream>
#include <map>
#include <algorithm>
int main()
{
std::map<std::string, int> map = {{ "HELLO", 1 }, { "WORLD", 2 }};
std::cout << "before:\n";
for (auto& kv : map)
{
std::cout << '\t' << kv.first << ":" << kv.second << '\n';
}
// create a new map with lowercase keys
std::map<std::string, int> out;
std::for_each(map.begin(), map.end(), [&](auto& kv)
{
std::string lower;
std::transform(kv.first.begin(), kv.first.end(), std::back_inserter(lower), tolower);
out[lower] = kv.second;
});
std::cout << "after:\n";
for (auto& kv : out)
{
std::cout << '\t' << kv.first << ":" << kv.second << '\n';
}
return 0;
}
中修改键,因此您必须创建新地图
有些事情:
示例:
before:
HELLO:1
WORLD:2
after:
hello:1
world:2
输出:
{
// Is git enabled
"git.enabled": true,
// Path to the git executable
"git.path": "C:\\path\\to\\git.exe"
// other settings
}
答案 1 :(得分:1)
std::transform
将仿函数的结果分配给目标范围内的元素。这意味着目标迭代器必须是与输入范围大小相同的范围的起点。在您的示例中,目标是空地图。转换本质上是以下循环:
std::map <string, int> M;
std::map<string, int> M1;
for(auto i=M.begin(), j=M1.begin(); i != M.end(); ++i,++j)
{
*j = f(*i);
}
减少j
对于空容器是非法的,并且对于地图没有意义,因为您无法更改密钥。
您可以从此代码中看到,您的lambda也不正确。它应该将一个(键值)对转换为目标类型的对象。在您的情况下,目标类型是相同的。
您必须先调整目标容器的大小,例如:通过调用resize
(如果它是一个向量),或者使用一个迭代器来使赋值适应map::insert
。 STL为此提供了适配器:
#include <map>
#include <string>
#include <cctype>
#include <iterator>
#include <algorithm>
int main() {
std::map <std::string, int> M;
std::map<std::string, int> M1;
std::transform(M.begin(), M.end(), std::inserter(M1, M1.begin()),
[](std::pair<const std::string, int> const & p)
{
std::string lowercase;
std::transform( p.first.begin(), p.first.end(),
std::back_inserter(lowercase),
[](auto c) {return std::tolower(c);} );
return std::make_pair(lowercase, p.second);
});
return 0;
}
答案 2 :(得分:1)
如果您想要使用std::transform
,那么您可以使用以下方法
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
#include <cctype>
#include <iterator>
#include <utility>
int main ()
{
std::map<std::string, int> m1 = { { "FIRST", 1 }, { "SECOND", 2 } };
for ( const auto &p : m1 )
{
std::cout << p.first << '\t' << p.second << std::endl;
}
auto to_lower_case = []( const std::pair<const std::string, int> &p )
{
std::string t; t.reserve( p.first.size() );
std::transform( p.first.begin(), p.first.end(),
std::back_inserter( t ), ::tolower );
return std::make_pair( t, p.second );
};
std::cout << std::endl;
std::map<std::string, int> m2;
std::transform( m1.begin(), m1.end(),
std::inserter( m2, m2.begin() ), to_lower_case );
for ( const auto &p : m2 )
{
std::cout << p.first << '\t' << p.second << std::endl;
}
}
程序输出
FIRST 1
SECOND 2
first 1
second 2
在程序中,使用std::transform
两次。