- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
在 Linux 环境中使用 C++ 工作时,我遇到了一种情况,其中定义了多个整数范围,并且整数输入根据它们所属的范围映射到不同的任意整数。没有一个范围重叠,而且它们并不总是连续的。
解决这个问题的“最简单”的方法是为每个范围使用一堆 if 语句,但是范围的数量、它们的界限和目标值都可以变化,因此 if 语句是不可维护的。
例如,范围可能是 [0, 70],称为 r_a,[101, 150],称为 r_b,和 [201, 400],称为 r_c。 r_a 中的输入映射到 1,r_b 中的输入映射到 2,r_c 映射到 3。任何不在 r_a、r_b、r_c 中的都映射到 0。
我可以想出一个数据结构和算法来存储(边界, map 目标)的元组并遍历它们,因此找到目标值需要在边界对的数量上线性时间。我还可以想象一种方案,它使对保持有序并针对所有下限(或上限)使用二进制排序算法,找到最接近输入的,然后与相反的界限进行比较。
有没有比基于二分搜索的算法更好的方法来完成映射?更好的是,是否有一些 C++ 库已经可以做到这一点?
最佳答案
这里最好的方法确实是二分搜索,但是任何有效的基于顺序的搜索都会做得很好。您实际上不必显式地实现搜索和数据结构。您可以通过使用标准关联容器来间接使用它。
由于您的范围不重叠,因此解决方案非常简单。您可以立即使用 std::map
解决此问题,只需几行代码即可解决。
例如,这是一种可能的方法。假设我们将一个 [ int, int ]
范围映射到一个 int
值。让我们将我们的范围表示为封闭开放范围,即如果原始范围是 [0, 70]
,让我们考虑一个 [0, 71)
范围。另外,让我们使用 0
的值作为“保留”值,这意味着“没有映射”(正如您在问题中要求的那样)
const int EMPTY = 0;
您需要做的就是声明一个从 int
到 int
的映射:
typedef std::map<int, int> Map;
Map map;
并用您的封闭式开放范围的每一端填充它。左(封闭)端应该映射到整个范围映射到的所需值,而右(开放)端应该映射到我们的 EMPTY
值。对于您的示例,它将如下所示
map[0] = r_a;
map[71] = EMPTY;
map[101] = r_b;
map[251] = EMPTY;
map[260] = r_c; // 260 adjusted from 201
map[401] = EMPTY;
(我调整了您的最后一个范围,因为在您的原始示例中它与前一个范围重叠,并且您说您的范围不重叠)。
这就是初始化。
现在,为了确定 i
的给定值映射到哪里,您需要做的就是
Map::iterator it = map.upper_bound(i);
如果 it == map.begin()
,则 i
不在任何范围内。否则,做
--it;
如果it->second
(对于递减的it
)是EMPTY
,那么i
不是在任何范围内。
组合的“未命中”检查可能如下所示
Map::iterator it = map.upper_bound(i);
if (it == map.begin() || (--it)->second == EMPTY)
/* Missed all ranges */;
否则,it->second
(对于递减的it
)是您的映射值
int mapped_to = it->second;
请注意,如果原始范围是“接触”的,如 [40, 60]
和 [61, 100]
,则封闭-开放范围将看起来as [40, 61)
和 [61, 101)
表示 61
的值将在 map 初始化期间映射两次。在这种情况下,确保 61
的值映射到正确的目标值而不是 EMPTY
的值很重要。如果您按照从左到右(即递增)的顺序映射如上所示的范围,它将自行正常工作。
注意,只有范围的端点被插入到映射中,这意味着内存消耗和搜索的性能仅取决于范围的总数,而与它们的总长度完全无关。
如果你愿意,你可以在初始化过程中添加一个“守卫”元素到 map 中
map[INT_MIN] = EMPTY;
(对应“负无穷大”)和“未命中”检查会变得更简单
Map::iterator it = map.upper_bound(i);
assert(it != map.begin());
if ((--it)->second == EMPTY)
/* Missed all ranges */;
但这只是个人喜好问题。
当然,如果你只是想为非映射值返回0
,你根本不需要进行任何检查。只需从递减的迭代器中取出 it->second
即可。
关于c++ - 从整数范围映射到任意单个整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2202262/
我想要以下内容: void foo( /* something representing a function f */, /* arguments a1, a2, etc. in s
简而言之,我想声明一个这样的特征: trait Test { def test(amount: Int): A[Int] // where A must be a Monad } 这样我就可以
在 GWT 中,如何在 onModuleLoad 方法中插入框架集以及相对嵌套的框架集和框架,以合并许多小程序和其他小部件和 HTML?代码片段是: 公共(public)类 MainEntryPoin
这个问题在这里已经有了答案: How do I best simulate an arbitrary univariate random variate using its probability
我对java相当陌生,并且习惯于枚举本质上只不过是一个命名的整数列表。 现在我正在编写一个实现,其中父类有几个采用枚举值作为参数的方法。枚举将在子类中定义,并且会略有不同。由于枚举基本上看起来像类,所
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
想象一下 6-7 台服务器的设置都完全相同Java 版本“1.6.0_18”OpenJDK 运行时环境 (IcedTea6 1.8) (fedora-36.b18.fc11-i386)OpenJDK
这个问题在这里已经有了答案: What are some uses of template template parameters? (10 个答案) 关闭 4 年前。 我有一个根据策略舍入值的函数
我正在寻找如何在 Java 中给定一个 Async CompletableFutures 列表,以便前 N 个中的任何一个成功完成或失败。除非没有 N 次成功,否则忽略任何失败。 有这方面的例子吗?
我面临的问题是项目已经使用集群编程来分配任务。 if (cluster.isMaster) { // Fork workers. for (var i = 0; i { }); } el
我正在为 Luxology modo(3D 和 VFX 应用程序)编写脚本,该脚本使用 python 作为脚本语言。在我的脚本中的某个位置,我正在读取从其他应用程序输出的文本文件,并从该文本文件的行创
这个问题在这里已经有了答案: Fast arbitrary distribution random sampling (inverse transform sampling) (5 个答案) 关闭
我只是遇到了一个问题,我有一个结构数组,例如 package main import "log" type Planet struct { Name string `json:"
我正在尝试将 class ResponseResult 编码为 json case class ResponseResult (var Code : Int, var
我想将一个矩阵中的一个 block 复制到另一个矩阵的一部分中。要将其与任何类型的 n 维数组一起使用,我需要通过 [] 运算符应用带有偏移量的列表。有办法做到这一点吗? mat_bigger[0:5
我有一个匹配一组数字和字母的正则表达式。但是我希望能够排除任何三个连续的字母。这是为了防止意外形成单词或缩写。 我的表达如下。它还排除了一些类似的字符,如 0、o、O 和 1、i、I、l): ^[2-
根据documentation . 应匹配任何字符,但不匹配重音字符。 mysql> select 'test' regexp 't.st'; +----------------------+ | '
我该如何用 JavaScript 编写这个 if 语句? if(url == "http://www.google.com/" && "*") { ... } * 需要灵活并接受添加到第一个变量上
我知道 cPython 有一个 GIL,因此如果不使用多处理模块,您的脚本就无法在多个内核上运行。但是有什么可以阻止内置功能,例如使用多核进行排序吗?我不了解 cPython 结构,但我想我要问的问题
寻找命令行 gdb 的替代方法来检查 OSX 上的核心转储 - 有没有办法让 Xcode 打开带有调试符号的任意核心转储? 最佳答案 您是否尝试过使用 MachOView 1? 听起来它可能适用于查看
我是一名优秀的程序员,十分优秀!