始终查找第二个最近的值 return 最后一个最近的值

Find second nearest value always return last nearest value

我想从我的数据集中找到最接近的值。第一个值是 return 正确的数据,但第二个值是 return 最后最近的数据。例如,如果我有 7, 11, 12, 15, 17, 20 并且我的参数值为 10,它应该 return 第一个最近的值 = 11,第二个最近的值 = 12。但是当我尝试时,第二个值不是 12,而是 20。第一个值将给出正确的 return 但第二个最近的值将始终显示最后一个最近的值,而不是第二个最近的值。

这是我的代码:

String closestPosition = null;

            ArrayList<Router> wifis = db.getFriendlyWifis(building);

            double min_distance = positionData.uDistance(positionsData.get(0), wifis);
            closestPosition = positionsData.get(0).getName();
            String res = "";
            res += closestPosition + "\n" + min_distance;
            res += "\n" + positionsData.get(0).toString();
            int j=0;
            for (int i = 1; i < positionsData.size(); i++) {
                double distance = positionData.uDistance(positionsData.get(i), wifis);
                res += "\n" + positionsData.get(i).getName() + "\n" + distance;
                res += "\n" + positionsData.get(i).toString();
                if (distance < min_distance) {
                    min_distance = distance;
                    closestPosition = positionsData.get(i).getName();
                    j=i;
                }

            }
            if (min_distance == PositionData.MAX_DISTANCE){
                closestPosition="OUT OF RANGE";
                Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();

            }
            result.setText("Nearest point :  "+ closestPosition);
            res += "\nCurrent:\n" + positionData.toString();
            Log.v("Result",res);
            //////////////////////////////////////////////////

            min_distance = positionData.uDistance(positionsData.get(0), wifis);
            String closestPosition2 = null;

            closestPosition2 = positionsData.get(0).getName();
            res = "";
            res += closestPosition2 + "\n" + min_distance;
            res += "\n" + positionsData.get(0).toString();
            for (int i = 1; i < positionsData.size(); i=i+2) { if(j!=i){
                    double distance = positionData.uDistance(positionsData.get(i), wifis);
                    res += "\n" + positionsData.get(i).getName() + "\n" + distance;
                    res += "\n" + positionsData.get(i).toString();
                    closestPosition2 = positionsData.get(i).getName();//////////////////////////
                    if(closestPosition2.equals(closestPosition))
                        continue;
                    if (distance < min_distance) {
                        min_distance = distance;
                        closestPosition2 = positionsData.get(i).getName();

                    }
                }
            }

            if (min_distance == PositionData.MAX_DISTANCE){
                closestPosition2="OUT OF RANGE";
                Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();

            }
            result2.setText("Nearest point :  "+ closestPosition2);

这是输出:

V/closest1:: f
V/closest2:: e

这是日志:

 d
    36.0
    d(4.0,4.0)
    UGM-Secure : -63.0
    eduroam : -63.0
    UGM-Hotspot : -42.0

    a
    64.0
    a(1.0,1.0)
    UGM-Hotspot : -40.0

    f
    17.0
    f(6.0,6.0)
    UGM-Secure : -65.0
    eduroam : -66.0
    UGM-Hotspot : -46.0

    b
    25.0
    b(2.0,2.0)
    UGM-Secure : -60.0
    eduroam : -59.0
    UGM-Hotspot : -48.0

    c
    89.0
    c(3.0,3.0)
    UGM-Secure : -60.0
    eduroam : -59.0
    UGM-Hotspot : -40.0

    e
    94.0
    e(5.0,5.0)
    UGM-Secure : -65.0
    eduroam : -66.0
    UGM-Hotspot : -39.0

如果第一个最近的值是f,值为17,第二个最近的值是b还是d对吗?但为什么它 return e 具有最远的价值?实际上,我也在寻找第三个最近的值,如果还有找到第三个最近的值的方法,那就太好了。

编辑:这是我的位置数据class

public class PositionData implements Serializable {
    public static final int MAX_DISTANCE=99999999;
    private String name;
    double x;
    double y;
    public static final int MINIMUM_COMMON_ROUTERS=1;
    public HashMap<String, Double> values;
    public HashMap<String,String> routers;



    public PositionData(String name, double x, double y) {
        // TODO Auto-generated constructor stub
        this.name=name;
        this.x=x;
        this.y=y;
        values = new HashMap<String, Double>();
        routers = new HashMap<String, String>();

    }



    public void addValue(Router router, double strength){

        values.put(router.getBSSID(), strength);
        routers.put(router.getBSSID(),router.getSSID());

    }
    public String getName() {
        return name;
    }

    public Double getX() {
        return x;
    }

    public Double getY() {
        return y;
    }

    public String toString() {
        String result="";
        result+=name+"("+x+","+y+")"+"\n";
        for(Map.Entry<String, Double> e: this.values.entrySet())
            result+=routers.get(e.getKey())+" : "+e.getValue().toString()+"\n";

        return result;

    }
    public HashMap<String, Double> getValues() {
        return values;
    }
    public double uDistance(PositionData arg,ArrayList<Router> friendlyWifis){
        double sum=0;
        double count=0;
        for(Map.Entry<String, Double> e: this.values.entrySet()){
            Double v;
            //Log.v("Key : ",arg.values.get(e.getKey()).toString());
            if(isFriendlyWifi(friendlyWifis,e.getKey()) && arg.values.containsKey(e.getKey()))
            {
                v=arg.values.get(e.getKey());
                sum+=Math.pow((v-e.getValue()),2);
                count++;
            }
        }
        if(count<MINIMUM_COMMON_ROUTERS){
            sum=MAX_DISTANCE;
        }

        return sum;
    }

    private boolean isFriendlyWifi(ArrayList<Router> wifis, String bssid){
        for(int i=0;i<wifis.size();i++){
            if(wifis.get(i).getBSSID().equals(bssid))
                return true;

        }
        return false;

    }

}

这将为您提供最接近的值

int[] numbers = new int[10];
numbers[0] = 100;
numbers[1] = -34200;
numbers[2] = 3040;
numbers[3] = 400433;
numbers[4] = 500;
numbers[5] = -100;
numbers[6] = -200;
numbers[7] = 532;
numbers[8] = 6584;
numbers[9] = -945;

int myNumber = 50;
int distance = Math.abs(numbers[0] - myNumber);
int idx = 0;
for(int c = 1; c < numbers.length; c++){
    int cdistance = Math.abs(numbers[c] - myNumber);
    if(cdistance < distance){
        idx = c;
        distance = cdistance;
    }
}
int nearestNumber = numbers[idx];

试试下面的代码:

    private final static int POSITIONS_ARRAY_SIZE = 3; //Global constant in the Activity.


    String closestPosition = null;
    String closestPosition2 = null;
    String closestPosition3 = null;
    ArrayList<Router> wifis = db.getFriendlyWifis(building);
    boolean flagPositionInserted;

    ArrayList<Integer> min_distance_positions = new ArrayList<>();
    //Get the first value (position = 0).
    double min_distance = positionData.uDistance(positionsData.get(0), wifis);
    min_distance_positions.add(0);
    String res = "";
    res += closestPosition + "\n" + min_distance;
    res += "\n" + positionsData.get(0).toString();

    //Iterate through the datalist (positionsData).
    for (int i = 1; i < positionsData.size(); i++) {
        double distance = positionData.uDistance(positionsData.get(i), wifis);
        res += "\n" + positionsData.get(i).getName() + "\n" + distance;
        res += "\n" + positionsData.get(i).toString();

        flagPositionInserted = false;
        //Iterate through the sorted list (min_distance_positions).
        for (int j = 0; j < min_distance_positions.size(); j++){
            if (distance < positionData.uDistance(positionsData.get(min_distance_positions.get(j)), wifis)) {
                min_distance_positions.add(j, i);
                flagPositionInserted = true;
                break;
            }
        }
        if (!flagPositionInserted) {
            if (min_distance_positions.size() < POSITIONS_ARRAY_SIZE) {
                min_distance_positions.add(i);
            }
        }
    }

    //min_distance_positions.size() should be less or equal to 3(POSITIONS_ARRAY_SIZE).
    //min_distance_positions.get(0) is the closestPosition.
    //min_distance_positions.get(1) is the 2nd closestPosition.
    //min_distance_positions.get(2) is the 3rd closestPosition.
    String msg = "";
    for (int i = 0; i < min_distance_positions.size(); i++){
        msg += min_distance_positions.get(i) + ", ";
    }
    Log.v("Result", "Position ArrayList Content: " + msg);

    closestPosition = positionsData.get(min_distance_positions.get(0)).getName();
    if (positionData.uDistance(positionsData.get(min_distance_positions.get(0)), wifis) >= PositionData.MAX_DISTANCE){
        closestPosition="OUT OF RANGE";
        Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
    }
    result.setText("Nearest point :  "+ closestPosition);
    res += "\nCurrent:\n" + positionData.toString();
    Log.v("Result", res);

    closestPosition2 = positionsData.get(min_distance_positions.get(1)).getName();
    if (positionData.uDistance(positionsData.get(min_distance_positions.get(1)), wifis) >= PositionData.MAX_DISTANCE){
        closestPosition2="OUT OF RANGE";
        Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
    }
    result2.setText("Nearest point :  "+ closestPosition2);
    closestPosition3 = positionsData.get(min_distance_positions.get(2)).getName();
    if (positionData.uDistance(positionsData.get(min_distance_positions.get(2)), wifis) >= PositionData.MAX_DISTANCE){
        closestPosition3="OUT OF RANGE";
        Toast.makeText(this,"You are out of range of the selected building",Toast.LENGTH_LONG).show();
    }
    result3.setText("Nearest point :  "+ closestPosition3);

代码是使用INSERTION SORT根据点的距离对点进行排序,并将点位置存储在另一个ArrayList(min_distance_positions)中。根据您的示例数据,原始顺序为:d(位置 0)、a(位置 1)、f(位置 2)、b(位置 3)、c(位置 4)、e(位置 5)。排序顺序为:2(f)、3(b)、0(d)、1(a)、4(c)、5(e)。 if (min_distance_positions.size() < POSITIONS_ARRAY_SIZE)是控制输出ArrayList(min_distance_positions)的大小,所以现在msg只有:2,3,0,。如果省略此代码,则消息为:2, 3, 0, 1, 4, 5,

希望对您有所帮助!

  import java.util.Arrays;
    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello World");
            int[] numbers = new int[10];
            numbers[0] = 100;
            numbers[1] = -34200;
            numbers[2] = 3040;
            numbers[3] = 400433;
            numbers[4] = 500;
            numbers[5] = -100;
            numbers[6] = -100;
            numbers[7] = 532;
            numbers[8] = 6584;
            numbers[9] = -945;
            // my number 
            int myNumber = 150;
            Arrays.sort(numbers);

// for first nearest value
            int num = valnearest(numbers, myNumber);
            int firstnearestNumber = numbers[num];
            System.out.println("firstnearestNumber--->" + firstnearestNumber);

 // for Second nearest value
            numbers = removeTheElement(numbers, num);

            int newnum = valnearest(numbers, myNumber);
            int secondnearestNumber = numbers[newnum];
            System.out.println("secondnearestNumber--->" + secondnearestNumber);

        }

        public static int valnearest(int[] numbers, int myNumber) {
            int idx = 0;
            int lastdistance = -1;
            for (int c = 0; c < numbers.length; c++) {
                int distance = Math.abs(numbers[c] - myNumber);

                if (lastdistance != -1) {
                    if (distance < lastdistance) {
                        idx = c;
                    }
                }
                lastdistance = distance;

            }

            return idx;
        }

        public static int[] removeTheElement(int[] arr,
                                             int index) {

            // If the array is empty 
            // or the index is not in array range 
            // return the original array 
            if (arr == null
                    || index < 0
                    || index >= arr.length) {

                return arr;
            }

            // Create another array of size one less 
            int[] anotherArray = new int[arr.length - 1];

            // Copy the elements except the index 
            // from original array to the other array 
            for (int i = 0, k = 0; i < arr.length; i++) {

                // if the index is 
                // the removal element index 
                if (i == index) {
                    continue;
                }

                // if the index is not 
                // the removal element index 
                anotherArray[k++] = arr[i];
            }

            // return the resultant array 
            return anotherArray;
        }
    }