查找值落入哪个箱
Finding which bin a values fall into
我试图找到双x属于哪个类别C。我的类别被定义为字符串名称,并在这样的文件中将值加倍
A 1.0
B 2.5
C 7.0
应该这样解释
"A": 0 < x <= 1.0
"B": a < x <= 2.5
"C": b < x <= 7.0
(输入可以具有任意长度,并且可能必须按其值排序(。我只需要这样的函数
std::string findCategory(categories_t categories, double x) {
...insert magic here
}
所以对于这个例子,我希望
findCategory(categories, 0.5) == "A"
findCategory(categories, 1.9) == "B"
findCategory(categories, 6.0) == "C"
所以我的问题是 a( 如何编写函数和 b( category_t的最佳选择是什么(在 11 C++ 之前使用 stl(。我做了几次尝试,都是...不太成功。
一种选择是使用带有双精度作为键的 std::map
容器,以及与分配给其上限为给定值的范围的值相对应的值。 例如,给定您的文件,您将拥有如下所示的地图:
std::map<double, std::string> lookup;
lookup[1.0] = "A";
lookup[2.5] = "B";
lookup[7.0] = "C";
然后,您可以使用给定某个点的 std::map::lower_bound
函数来获取键/值对,其键(上端点(是映射中至少与相关点一样大的第一个键。 例如,使用上面的映射,lookup.lower_bound(1.37)
将返回值为"B"的迭代器。 lookup.lower_bound(2.56)
将返回值为"C"的迭代器。 这些查找速度很快;对于具有 n 个元素的映射,它们需要 O(log n( 时间。
在上面,我假设您查找的值都是非负值。 如果允许负值,则可以添加快速测试,以在执行任何查找之前检查该值是否为负值。 这样,您可以消除虚假结果。
值得一提的是,如果您碰巧知道查找的分布(例如,它们是均匀分布的(,则可以构建一种称为最佳二叉搜索树的特殊数据结构,该结构将提供比std::map
更好的访问时间。 此外,根据您的应用,可能会有更快的选项可用。 例如,如果你这样做是因为你想随机选择一个具有不同概率的结果,那么我建议你研究这篇关于别名方法的文章,它允许你在 O(1( 时间内生成随机值。
希望这有帮助!
您可以使用配对类型和算法中的"lower_bound"<>http://www.cplusplus.com/reference/algorithm/lower_bound/。
让我们根据上边缘定义您的类别: Typedef 对 categories_t;
然后只需制作这些边缘的向量并使用二叉搜索进行搜索。请参阅下面的完整示例。
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
typedef pair<double,string> category_t;
std::string findCategory(const vector<category_t> &categories, double x) {
vector<category_t>::const_iterator it=std::lower_bound(categories.begin(), categories.end(),category_t(x,""));
if(it==categories.end()){
return "";
}
return it->second;
}
int main (){
vector< category_t > edges;
edges.push_back(category_t(0,"bin n with upper edge at 0 (underflow)"));
edges.push_back(category_t(1,"bin A with upper edge at 1"));
edges.push_back(category_t(2.5,"bin B with upper edge at 2.5"));
edges.push_back(category_t(7,"bin C with upper edge at 7"));
edges.push_back(category_t(8,"bin D with upper edge at 8"));
edges.push_back(category_t(9,"bin E with upper edge at 9"));
edges.push_back(category_t(10,"bin F with upper edge at 10"));
vector< double > examples ;
examples.push_back(1);
examples.push_back(3.3);
examples.push_back(7.4);
examples.push_back(-5);
examples.push_back(15);
for( vector< double >::const_iterator eit =examples.begin();eit!=examples.end();++eit)
cout << "value "<< *eit << " : " << findCategory(edges,*eit) << endl;
}
比较按照我们想要的方式工作,因为双精度是货币对中的第一个,并且首先通过比较第一个成分来比较配对,然后比较第二个成分。否则,我们将定义一个比较谓词,如我上面链接的页面中所述。
- 正在查找文档以获得PS4平台的C++中的设备信息
- 在C++中查找文件
- 模板元程序查找相似的连续类型名称
- 在UNIX系统中使用DIR查找文件的字节大小
- 查找最接近的大于当前数字的数字的索引
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 查找后更改类变量
- 使用正则表达式regex_search在字符串中查找字符串
- 使用gcc从静态链接的文件中查找可选符号
- 在C++中查找范围的长度
- 算法问题:查找从堆栈中弹出的所有序列
- 在Windows中查找扬声器输出的当前音量级别
- 如何在C++中使用X509证书模在令牌中查找私钥
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 在 for 循环中查找问题时遇到困难
- 如何在文件中查找字节序列
- 试图创建一个多线程程序来查找0-100000000之间的总素数
- 使用堆查找第K个最大元素的时间复杂性
- 一个函数,用于查找字符串1包含字符串2 c++的次数