js支持的整数的有效范围
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js支持的整数的有效范围相关的知识,希望对你有一定的参考价值。
参考技术A js支持的整数的有效范围是,-2的53次方至2的53次方也就是-9007199254740992~9007199254740992。
可以在浏览器里输入在这个范围之外的数试试,返回的值多数跟输入不一样。
实际应用,后台传过来的是16位整数,可能会导致一些查询操作得不到正确的结果
因此建议传递16位及以上的整数时,转化为字符串传输。
在某些范围更新后获得整数数组的最终状态的有效算法是什么?
我给了一个数组arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
。我必须做一些范围更新。在每次更新中,我将获得三个整数left, right, new_value
。这意味着我必须将arr
的所有元素从索引left
更新为right
(从0开始的索引)到new_value
。最后,我必须告诉这些更新后数组arr
的最终状态是什么。
在这种情况下,假设有2个更新。第一次更新说将0...3
更新到13
,第二次更新说要将2...6
更新为0
。 arr
的最终状态是{13, 13, 0, 0, 0, 0, 0, 8, 9, 10}
。这是我试过的代码:
int main()
{
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (size_t i = 1; i <= 2; i++)
{
int left, right, new_value;
cin >> left >> right >> new_value;
for (size_t j = left; j <= right; j++)
{
arr[j] = new_value;
}
}
for (size_t i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
}
但问题是如果数组的大小是n
并且有q
查询。然后我的方法的时间复杂性是O(n * q).
我的问题是什么将是一个更好的方法?
您需要做的是创建一个中间数据结构,该结构对于进行范围更新而言很便宜。
最简单的数据结构是树。一个实现可以使树的每个节点包含以下字段:
left_index
right_index
left_subtree
right_subtree
is_constant
value
您可以在时间O(n)
填充它,使得索引填充,索引相同,子树null,is_constant
true和值,然后用is_constant
false填充所有上层。
每个更新查询只涉及从上到下遍历。诀窍在于,如果你在树中将is_constant
设置得更高,则不需要更新它下面的子树 - 它们都将被“屏蔽”。因此每次更新都是时间O(log(n))
。
从树复制到您的阵列再次是O(n)
操作。
树代码将是适度棘手的,但q
查询的总时间是O(n) + O(q * log(n)) + O(n) = O(n + q * log(n))
。这是对O(q * n)
的重大改进。
以下是树更新的工作原理。
所以我们有一棵树。我们有三个值,left, right, value
。然后,更新通过以下Pythonish伪代码递归进行:
def update_tree (self, left, right, value):
if right < left:
return # empty interval
elif right < self.left_index:
return # No overlap
elif self.right_index < left:
return # No overlap
elif left <= self.left_index and self.right_index <= right:
# No need to update the subtree - this is our win.
self.is_constant = True
self.value = value
else:
# We need to only update part of this tree.
self.is_constant = False
self.left_subtree.update_tree(left, right, value)
self.right_subtree.update_tree(left, right, value)
有效地执行此操作的最简单方法是维护一个有序集合,该集合仅存储索引0的值以及那些值与前一个索引不同的索引。
由于您使用的是C ++,因此可以将index - > value映射放在std::map<int,int>
中。
在每次更新时,您花费O(log n)时间来查找修改地图的位置(使用map.lower_bound
),然后您将添加最多2个条目,并且可能删除一些预先存在的条目或您添加的一些条目之前。
预先存在的条目总数<= n,您添加的条目总数<= 2q,因此删除的条目总数为<= n + 2q。
总的复杂性是O(n + q * log n)
这似乎也是优先级队列的情况。将查询的每个左右部分与适当的数组单元相关联。
[(13,1), 2, (0,2), (-13,1), 5,
6, (-0,2), 8, 9, 10]
(If more than one fall on one cell,
aggregate them.)
现在,当我们从左到右遍历时,我们对一件事情感兴趣:我们当前在哪个更新间隔(如果有的话)在最后的查询中提供?后者“排名”是查询部分的优先级。
我们从(13,1)开始,我们将其置于优先级队列中并保持输出13直到达到(0,2)。我们将(0,2)添加到优先级队列,这需要更高的优先级。我们继续输出0.我们到达(-13,1),它告诉我们从优先级队列中删除(13,1),并继续putput 0直到(-0,2)调用删除(0,2) )。我们以8,9,10结束。
将间隔代数应用于您的查询。新查询优先于旧查询。在您发布的情况下,您可以从一张干净的纸张开始第一个查询添加了事务
0 3 13
第二个更新此表
0 1 13 // note the range change -- intervals may not overlap
2 6 0
大多数语言都有间隔模块,可以为您提供支持。对您的表进行排序,使得对于新查询的每个端点,搜索不会比O(log q)差 - 并且直接索引方法会将此删除为O(n)。
在您不在查询之前不要进行任何更新。间隔过程为O(q),更新为O(n),因此您的总体复杂度为O(q + n)。
以上是关于js支持的整数的有效范围的主要内容,如果未能解决你的问题,请参考以下文章