假设我有一个按其元素的priority
属性排序的列表,这是一个数字。我知道列表中每个成员的priority
值,但我想将一个元素移动到特定索引。是否可以通过仅修改我想要移动的元素的priority
来实现此目的?
priority
不一定是整数。任何算法都可用于确定元素priority
需要的内容,但priority
必须是唯一的。
我认为在所需索引之前和之后获取元素的priority
,但我不知道如何在它们之间选择一个最终不会导致重复的数字。如果我之前只为元素添加一些给定值(整数或十进制),我最终会获得与之后元素相同的值。使用两者之间的范围调用random()
会起作用,但这似乎是真正迂回的做事方式。
如果这种操作有名字,我也有兴趣学习它。
答案 0 :(得分:1)
值m =(大+低)/ 2总是在两个值的中间。
有关编号的进一步阅读,请参阅讲座: http://www.cs.uni-paderborn.de/fachgebiete/ag-boettcher/lehre/ss2012/dbis-2/download.html
答案 1 :(得分:1)
(上/下)/ 2怎么样?
在@msander的答案上扩展一下,您可以使用字母数字优先级来确保始终具有“中间”优先级来分配。如果你需要分配许多优先级,两个连续优先级之间的距离会越来越低,最终会失去精度,你会得到像((上+下)/ 2 ===更低)。
如果您更改获得中间优先级的方式,则可以使用字符串(不会丢失精度),而不是实际数字。例如,如果您的优先级是字符串式数字(由0,1,2,3,4,5,6,7,8,9组成的字符串):
['1','3','4']
在1到3之间移动4将导致: ['1','2','3']
在2和1之间移动3将导致: ['1','15','2']
在1到15之间移动2将导致: ['1','12','15']
您需要注意的是如何比较优先级(String.prototype.localeCompare)。
同样,如果您希望在精确丢失方面遇到麻烦,这个解决方案是值得的。
编辑(添加了计算优先级的函数):
免责声明:代码出乎意料地难以理解。如果有人有更好的想法,请随意插入。如果你只使用二进制字符串(只包含0和1的字符串),它将更容易编写。
function getMiddlePriority(p1, p2) {
var i=0,result = '';
// The identical digits need to be in the result
while ((p1[i] || '0') === (p2[i] || '0')) {
result += p1[i++] || '0';
}
// First different digit p1[i] !== p2[i]
// if the digits are far enough apart, there is a number between them
if ((p2[i]||0) - (p1[i]||0) > 1) {
return result + Math.floor(((+p2[i]||0) + (+p1[i]||0))/2);
}
// p2[i] === p1[i]+1
// Digits are close, need to parse some more digits to get a number between
var first = i++;
var k = 0;
while ((p1[i] === '9') && ((p2[i]||'0') === '0')) {
i++;
k++;
}
// p[i] is not 9 or p2[i] is not 0/undefined
if (p1[i] === '9') {
result += (p2[first]||'0') + repeat('0', k);
result += p2[i] === '1' ? '05' : Math.floor(p2[i]/2);
} else {
result += (p1[first]||'0') + repeat('9', k);
result += Math.floor((10 + (+p1[i] || 0))/2);
}
return result;
}
function repeat(character, count) {
var s = '';
while (count--) s+= character;
return s;
}
console.clear();
console.log('Expected 2 Got ' + getMiddlePriority('1', '3'));
console.log('Expected 25 Got ' + getMiddlePriority('2', '3'));
console.log('Expected 22 Got ' + getMiddlePriority('2', '25'));
console.log('Expected 21 Got ' + getMiddlePriority('2', '22'));
console.log('Expected 205 Got ' + getMiddlePriority('2', '21'));
console.log('Expected 202 Got ' + getMiddlePriority('2', '205'));
console.log('Expected 215 Got ' + getMiddlePriority('21', '22'));
console.log('Expected 1055 Got ' + getMiddlePriority('105', '106'));
console.log('Expected 10995 Got ' + getMiddlePriority('1099', '11'));
console.log('Expected 1105 Got ' + getMiddlePriority('1099', '111'));
字符串优先级的替代方法是使用数字优先级,并且每隔一段时间(当(upper+lower)/2 === lower || (upper+lower)/2 === upper
时)重新分配优先级。当然这不适合这个问题,因为对于N次重新排序,您不会进行1次更新,但是1+ N/S
会更新,其中S是在用完可用优先级之前可以执行的更新量。至少它是一个正确的解决方案(优先级永远是唯一的)。