我收到了不同大小的ArrayList
(width
和height
)。根据{{1}}尺寸,我希望在此ImageView
中获得更接近的宽度。
获得更接近数字的最佳算法是什么?
示例:宽度为1024.在此ArrayList
中有以下可能性:
答案 0 :(得分:2)
迭代数组。计算与"目标的距离"数组中每个宽度的宽度值(取差值的绝对值)。以最小距离跟踪物品。
伪代码,假设数组至少有一个元素:
int minDiff = Math.abs(targetWidth - width_of_item_0);
int minDiff_index = 0;
for (int i = 1; i < itemCount; i++)
{
int diff = Math.abs(targetWidth - width_of_item_i)
if (diff < minDiff)
{
minDiff = diff
minDiff_index = i
}
}
// minDiff_index now points at the closest item to targetWidth
答案 1 :(得分:0)
遍历数组(假设数组按升序排序),从宽度值中减去每个值,当减去的值不小于1时,计算宽度值和下面的值之间的绝对差值。降低该值,即最后一次减去的数组中的值以及接下来要减去的值。在这两个值中,给出最小差异的值应该是最接近的。
代码中解释的简单版本:
int width;
int result;
int[] widthArray;// the array is sorted in the ascending
....
int tempDiff=width-widthArray[0];
int i=1;
while(tempDiff<0 && i < widthArray.length){
tempDiff=width-widthArray[i];
i++
}
if(i==widthArray.length)
result=widthArray[i];
else
result=((width-widthArray[i-1])>(widthArray[i]-width))?
widthArray[i]:
widthArray[i-1];
答案 2 :(得分:0)
在java 1.8中,我将使用缩减操作:
int closest = options.stream()
.reduce(Integer.MAX_VALUE, (best, current) ->
Math.abs(current - target) < Math.abs(best - target) ? current : best);
答案 3 :(得分:0)
如果选项已排序且没有重复项(如您的示例中所示),则可以使用二进制搜索。如果存在完全匹配(然后您可以返回搜索值),或者使用-returnvalue-1
可以转换为插入点的负数,则会返回索引。
插入点是第一个数字的索引,该数字大于搜索值(如果没有,则为数组长度)。因此,如果我们在中间得到一个索引,我们只需要检查该索引处的数字和前一个索引的数字,该数字小于搜索值。既然我们知道,哪个值更小,哪个更大,我们不需要abs
来计算差异:
public static int getClosest(int number, int... from) {
int ix=Arrays.binarySearch(from, number);
if(ix>=0) { // exact match
return number;
}
ix=-ix-1;
return from[ix==0 || ix<from.length && number-from[ix-1]>from[ix]-number? ix: ix-1];
}
可以通过以下方式测试:
int width=1024;
int choice=getClosest(width, 58, 256, 512, 1048, 2090);
System.out.println(choice);
将打印1048
。但是要始终注意按排序顺序提供可用的选择而不重复...