Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在排序数组列表中查找2个最近的上一个值和2个最近的下一个值_Java_Search_Arraylist_Binary Search - Fatal编程技术网

Java 在排序数组列表中查找2个最近的上一个值和2个最近的下一个值

Java 在排序数组列表中查找2个最近的上一个值和2个最近的下一个值,java,search,arraylist,binary-search,Java,Search,Arraylist,Binary Search,这是一个修改过的二进制搜索,它返回排序数组列表中与给定值最近的元素。如何调整它,使其能够返回2个最近的前一个元素和2个最近的下一个元素 private static Long search(long value, ArrayList<Long> a) { if(value < a.get(0)) { return a.get(0); } if(value > a.get(a.size()-1)) { return

这是一个修改过的二进制搜索,它返回排序数组列表中与给定值最近的元素。如何调整它,使其能够返回2个最近的前一个元素和2个最近的下一个元素

private static Long search(long value, ArrayList<Long> a) {

    if(value < a.get(0)) {
        return a.get(0);
    }
    if(value > a.get(a.size()-1)) {
        return a.get(a.size()-1);
    }

    int lo = 0;
    int hi = a.size() - 1;

    while (lo <= hi) {
        int mid = (hi + lo) / 2;
        if (value < a.get(mid)) {
            hi = mid - 1;
        } else if (value > a.get(mid)) {
            lo = mid + 1;
        } else {
            return a.get(mid);
        }
    }
    return (a.get(lo) - value) < (value - a.get(hi)) ? a.get(lo) : a.get(hi);
}
私有静态长搜索(长值,ArrayList a){
if(值a.get(a.size()-1)){
返回a.get(a.size()-1);
}
int-lo=0;
int hi=a.大小()-1;
while(loa.get(mid)){
lo=中间+1;
}否则{
返回a.get(mid);
}
}
返回值(a.get(lo)-value)<(value-a.get(hi))?a、 得到(lo):得到(hi);
}
例如,让我考虑一下我的数组列表是由这些元素组成的:

[10120130140150160170180190110001]


我得到了730的值。我希望搜索返回一个由4个元素组成的数组,其中601、701作为前一个值,801和901作为下一个值。

有一种简单的方法可以扩展原始代码,以适应返回四个值的列表,而且相对容易:

    private static List<Long> search(long value, ArrayList<Long> a) {

    List<Long> returnList = new ArrayList<>();
    if (null == a) {
        return null;
    }
    if (a.isEmpty()) {
        return a;
    }
    if (a.size()==1) {
        return a;
    }
    if(value < a.get(0)) {
        returnList.add(a.get(0));
        returnList.add(a.get(1));
        return returnList;
    }
    if(value > a.get(a.size()-1)) {
        returnList.add(a.get(a.size()-1));
        returnList.add(a.get(a.size()-2));
        return returnList;
    }

    int lo = 0;
    int hi = a.size() - 1;

    while (lo <= hi) {
        int mid = (hi + lo) / 2;
        if (value < a.get(mid)) {
            hi = mid - 1;
        } else if (value > a.get(mid)) {
            lo = mid + 1;
        } else {
            if (mid>1) returnList.add(a.get(mid-2));
            if (mid>0) returnList.add(a.get(mid-1));
            if (mid<=a.size()-1) returnList.add(a.get(mid+1));
            if (mid<=a.size()-2) returnList.add(a.get(mid+2));
            return returnList;
        }
    }
    if ((a.get(lo) - value) < (value - a.get(hi))) {
        if (lo > 0) returnList.add(a.get(lo-1));
        returnList.add(a.get(lo));
        if (lo<=a.size()-1) returnList.add(a.get(lo+1));
        if (lo<=a.size()-2) returnList.add(a.get(lo+2)); 
    } else {
        if (lo > 1) returnList.add(a.get(hi-2));
        if (lo > 0) returnList.add(a.get(hi-1));
         ReturnList.add(a.get(hi));
        if (hi<=a.size()-1) returnList.add(a.get(hi+1));
    }
    return returnList;
}
私有静态列表搜索(长值,ArrayList a){
List returnList=new ArrayList();
如果(null==a){
返回null;
}
如果(a.isEmpty()){
返回a;
}
如果(a.size()==1){
返回a;
}
if(值a.get(a.size()-1)){
returnList.add(a.get(a.size()-1));
returnList.add(a.get(a.size()-2));
退货清单;
}
int-lo=0;
int hi=a.大小()-1;
while(loa.get(mid)){
lo=中间+1;
}否则{
如果(mid>1)returnList.add(a.get(mid-2));
如果(mid>0)returnList.add(a.get(mid-1));

如果(mid使用非常简单的方法,此代码将根据
lo
hi
mid
值之间的差异向结果列表添加元素

在边缘情况下,返回的元素数可以小于4。例如,如果左侧或右侧没有元素(由于列表边界),则返回的列表大小可以是2或3,具体取决于最近值的位置

如果这是您想要的,那么下面是代码:

private static List<Long> search(long value, List<Long> a) {
    if (a.size() < 3) return new ArrayList<>(a);
    List<Long> result = new ArrayList<>();
    if (value < a.get(0)) {
        result.add(a.get(0));
        result.add(a.get(1));
        return result;
    }
    if (value > a.get(a.size() - 1)) {
        result.add(a.get(a.size() - 2));
        result.add(a.get(a.size() - 1));
        return result;
    }

    int lo = 0;
    int hi = a.size() - 1;
    int match = -1;

    while (lo <= hi) {
        int mid = (hi + lo) / 2;
        if (value < a.get(mid)) {
            hi = mid - 1;
        } else if (value > a.get(mid)) {
            lo = mid + 1;
        } else {
            match = mid;
            break;
        }
    }

    if (match >= 0) {
        if (match > 1) result.add(a.get(match - 2));
        if (match > 0) result.add(a.get(match - 1));
        if (match < a.size() - 1) result.add(a.get(match + 1));
        if (match < a.size() - 2) result.add(a.get(match + 2));
    } else if (a.get(lo) < value) {
        result.add(a.get(hi));
        result.add(a.get(lo));
        if (lo < a.size() - 1) result.add(a.get(lo + 1));
        if (lo < a.size() - 2) result.add(a.get(lo + 2));
    } else if (a.get(hi) > value) {
        if (hi > 1) result.add(a.get(hi - 2));
        if (hi > 0) result.add(a.get(hi - 1));
        result.add(a.get(hi));
        result.add(a.get(lo));
    } else {
        if (hi > 0) result.add(a.get(hi - 1));
        result.add(a.get(hi));
        result.add(a.get(lo));
        if (lo < a.size() - 1) result.add(a.get(lo + 1));
    }

    return result;
}
私有静态列表搜索(长值,列表a){
如果(a.size()<3)返回新的ArrayList(a);
列表结果=新建ArrayList();
if(值a.get(a.size()-1)){
结果.添加(a.get(a.size()-2));
添加(a.get(a.size()-1));
返回结果;
}
int-lo=0;
int hi=a.大小()-1;
int match=-1;
while(loa.get(mid)){
lo=中间+1;
}否则{
匹配=中间;
打破
}
}
如果(匹配>=0){
如果(匹配>1)结果。添加(a.get(匹配-2));
如果(匹配>0)结果。添加(a.get(匹配-1));
if(match值,则为else{
如果(hi>1)结果,则添加(a.get(hi-2));
如果(hi>0)结果,则添加(a.get(hi-1));
结果。添加(a.get(hi));
结果。添加(a.get(lo));
}否则{
如果(hi>0)结果,则添加(a.get(hi-1));
结果。添加(a.get(hi));
结果。添加(a.get(lo));
如果(lo
是否总是有两个前一个值和两个下一个值?如果
已经在
列表中,输出应该是什么?我在下面写了一个答案-让我知道它是否有用。列表中已经存在的值对于我的实际数据集来说非常罕见。但是如果发生这种情况,它应该忽略该值并返回2 pr前一个值和2个下一个值。例如,如果给我值501,我希望列表返回[301、401、601、701]。非常感谢您的回答。这真的很有帮助。但是,也许我在问题中没有明确指出,我总是希望它返回两个以前的值和两个以后的值。例如,如果在您的代码中我输入700,则列表将返回[601、701、801、901]。我希望它返回[501、601、701、801].501和601是以前的值,701和801是下一个值。如果值已经在列表中,请检查我问题中关于该案例的注释。@法律我已根据您的规范对其进行了修改。它按您的预期工作。@法律根据您的注释进行编辑以忽略精确匹配谢谢!这正是我所需要的。@thelaw我很乐意帮忙!
public static void main(String[] args) {
    ArrayList<Long> list = new ArrayList(Arrays.asList(101l, 201l, 301l, 401l, 501l, 601l, 701l, 801l, 901l, 1001l));
    System.out.println(search(1020l,5,list));

}

[801, 901, 1001]

System.out.println(search(730l,4,list));

[601, 701, 801, 901]

System.out.println(search(601l,5,list));

[401, 501, 701, 801, 901]
private static List<Long> search(long value, List<Long> a) {
    if (a.size() < 3) return new ArrayList<>(a);
    List<Long> result = new ArrayList<>();
    if (value < a.get(0)) {
        result.add(a.get(0));
        result.add(a.get(1));
        return result;
    }
    if (value > a.get(a.size() - 1)) {
        result.add(a.get(a.size() - 2));
        result.add(a.get(a.size() - 1));
        return result;
    }

    int lo = 0;
    int hi = a.size() - 1;
    int match = -1;

    while (lo <= hi) {
        int mid = (hi + lo) / 2;
        if (value < a.get(mid)) {
            hi = mid - 1;
        } else if (value > a.get(mid)) {
            lo = mid + 1;
        } else {
            match = mid;
            break;
        }
    }

    if (match >= 0) {
        if (match > 1) result.add(a.get(match - 2));
        if (match > 0) result.add(a.get(match - 1));
        if (match < a.size() - 1) result.add(a.get(match + 1));
        if (match < a.size() - 2) result.add(a.get(match + 2));
    } else if (a.get(lo) < value) {
        result.add(a.get(hi));
        result.add(a.get(lo));
        if (lo < a.size() - 1) result.add(a.get(lo + 1));
        if (lo < a.size() - 2) result.add(a.get(lo + 2));
    } else if (a.get(hi) > value) {
        if (hi > 1) result.add(a.get(hi - 2));
        if (hi > 0) result.add(a.get(hi - 1));
        result.add(a.get(hi));
        result.add(a.get(lo));
    } else {
        if (hi > 0) result.add(a.get(hi - 1));
        result.add(a.get(hi));
        result.add(a.get(lo));
        if (lo < a.size() - 1) result.add(a.get(lo + 1));
    }

    return result;
}