如何在搜索时不使用std::map的自定义比较功能(map::find)?
How not to use custom comparison function of std::map in searching ( map::find)?
如您在我的代码中所见,lenMap
是一个 std::map
,带有 自定义比较函数 。这个函数只是检查字符串的长度。
现在当我想搜索一些键(使用map::find
)时,地图仍然使用自定义比较功能。
但是当我搜索某个键时,如何强制我的地图不使用它?
代码:
struct CompareByLength : public std::binary_function<string, string, bool>
{
bool operator()(const string& lhs, const string& rhs) const
{
return lhs.length() < rhs.length();
}
};
int main()
{
typedef map<string, string, CompareByLength> lenMap;
lenMap mymap;
mymap["one"] = "one";
mymap["a"] = "a";
mymap["foobar"] = "foobar";
// Now In mymap: [a, one, foobar]
string target = "b";
if (mymap.find(target) == mymap.end())
cout << "Not Found :) !";
else
cout << "Found :( !"; // I don't want to reach here because of "a" item !
return 0;
}
地图本身不提供这样的操作。比较仿函数的想法是创建一个内部排序以加快查找速度,因此元素实际上是根据您的仿函数排序的。
如果您需要以不同的方式搜索元素,您可以使用 STL 算法 std::find_if()
(具有线性时间复杂度)或创建使用另一个比较函子的第二个映射。
在您的具体示例中,由于您似乎只对字符串的长度感兴趣,因此您应该使用长度(std::size_t
类型)而不是字符串本身作为键。
顺便说一下,std::binary_function
不需要作为基础 class。从 C++11 开始,它甚至被弃用,例如参见 [=13=]。
比较函数告诉地图如何对元素进行排序以及如何区分它们。如果只比较长度,两个相同长度的不同字符串在map中会占据相同的位置(一个会覆盖另一个)。
要么将您的字符串存储在不同的数据结构中并对它们进行排序,要么试试这个比较函数:
struct CompareByLength
{
bool operator()(const string& lhs, const string& rhs) const
{
if (lhs.length() < rhs.length())
{
return true;
}
else if (rhs.length() < lhs.length())
{
return false;
}
else
{
return lhs < rhs;
}
}
};
我没有测试它,但我相信这将首先按长度排序字符串,然后通常会比较字符串。
您也可以使用 std::map<std::string::size_type, std::map<std::string, std::string>>
并使用第一个地图的长度和第二个地图的字符串值。您可能希望将其包装在 class 中以使其更易于使用,因为无法防止将其弄乱。
如您在我的代码中所见,lenMap
是一个 std::map
,带有 自定义比较函数 。这个函数只是检查字符串的长度。
现在当我想搜索一些键(使用map::find
)时,地图仍然使用自定义比较功能。
但是当我搜索某个键时,如何强制我的地图不使用它?
代码:
struct CompareByLength : public std::binary_function<string, string, bool>
{
bool operator()(const string& lhs, const string& rhs) const
{
return lhs.length() < rhs.length();
}
};
int main()
{
typedef map<string, string, CompareByLength> lenMap;
lenMap mymap;
mymap["one"] = "one";
mymap["a"] = "a";
mymap["foobar"] = "foobar";
// Now In mymap: [a, one, foobar]
string target = "b";
if (mymap.find(target) == mymap.end())
cout << "Not Found :) !";
else
cout << "Found :( !"; // I don't want to reach here because of "a" item !
return 0;
}
地图本身不提供这样的操作。比较仿函数的想法是创建一个内部排序以加快查找速度,因此元素实际上是根据您的仿函数排序的。
如果您需要以不同的方式搜索元素,您可以使用 STL 算法 std::find_if()
(具有线性时间复杂度)或创建使用另一个比较函子的第二个映射。
在您的具体示例中,由于您似乎只对字符串的长度感兴趣,因此您应该使用长度(std::size_t
类型)而不是字符串本身作为键。
顺便说一下,std::binary_function
不需要作为基础 class。从 C++11 开始,它甚至被弃用,例如参见 [=13=]。
比较函数告诉地图如何对元素进行排序以及如何区分它们。如果只比较长度,两个相同长度的不同字符串在map中会占据相同的位置(一个会覆盖另一个)。
要么将您的字符串存储在不同的数据结构中并对它们进行排序,要么试试这个比较函数:
struct CompareByLength
{
bool operator()(const string& lhs, const string& rhs) const
{
if (lhs.length() < rhs.length())
{
return true;
}
else if (rhs.length() < lhs.length())
{
return false;
}
else
{
return lhs < rhs;
}
}
};
我没有测试它,但我相信这将首先按长度排序字符串,然后通常会比较字符串。
您也可以使用 std::map<std::string::size_type, std::map<std::string, std::string>>
并使用第一个地图的长度和第二个地图的字符串值。您可能希望将其包装在 class 中以使其更易于使用,因为无法防止将其弄乱。