[英]How to use tolower with lambda function in map? C++
我想将存储在地图中的所有单词更改为小写。 使用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); });
您无法编辑map
键 ,因此您必须创建一个新地图
类似于以下内容:
例:
#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
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;
}
如果您想使用完全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
两次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.