有没有一种方法可以使用二进制搜索来获得特定的结果

问题描述

我的代码有效,但仅适用于初始切割值。我应该在getLetterGrade方法中使用二进制搜索算法来获得所需的结果,但是每次我只能得到一个结果。

Spring bean类

public class Grade implements GradeI {
    private String name;
    private int[] gradeBoundary = {100,90,85,80,77,73,70,0};
    private String[] gradeLetter = {"A+","A","A-","B+","B","B-","F"};
    private int count = 8;
    //private int key = 50;
    int result = Arrays.binarySearch(gradeBoundary,80);
    private String gradeLetterValue = null;

    public Grade() {
    }


    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setGradeBoundary(int[] grade) {
        this.gradeBoundary = grade;
    }

    public int[] getGradeBoundary() {
        return gradeBoundary;
    }

    public void setGradeLetter(String[] gradeLet) {
        this.gradeLetter = gradeLet;
    }

    public String[] getGradeLetter() {
        return gradeLetter;
    }

    public void setCount(int count) {
        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public String getLetterGrade(int numerical_grade) {

        if (numerical_grade < 70) {
            gradeLetterValue = "F";
        } else if (numerical_grade < 73) {
            gradeLetterValue = "B-";
        } else if (numerical_grade < 77) {
            gradeLetterValue = "B";
        } else if (numerical_grade < 80) {
            gradeLetterValue = "B+";
        } else if (numerical_grade < 85) {
            gradeLetterValue = "A-";
        } else if (numerical_grade < 90) {
            gradeLetterValue = "A";
        } else if (numerical_grade < 100) {
            gradeLetterValue = "A+";
        }

        return gradeLetterValue;
    }
}
    

主班

public class GradeApp {
            
public static void main(String[] args) {
                ApplicationContext context = new ClasspathXmlApplicationContext("GradeBeans.xml");
                Grade obj = (Grade) context.getBean("grade-bean");
                
                
                for(int i =66; i <=100; i++) {
                    
                    System.out.println(i+":"+ obj.getLetterGrade(i));
                }
        }
  }

The desired outcome is like this : 

66:F 67:F 68:F 69:F 70:B- 
71:B- 72:B- 73:B 74:B 75:B 
76:B 77:B+ 78:B+ 79:B+ 80:A- 
81:A- 82:A- 83:A- 84:A- 85:A 
86:A 87:A 88:A 89:A 90:A+ 
91:A+ 92:A+ 93:A+ 94:A+ 95:A+ 
96:A+ 97:A+ 98:A+ 99:A+ 100:A+ 

下面是我尝试二进制搜索的结果,当我在主程序中运行此代码时,我得到的唯一结果就是B +

    public String getLetterGrade(int numerical_grade) {
        int result = Arrays.binarySearch(gradeBoundary,7,80);

        if (result == 6) {
            gradeLetterValue = "F";
        } else if (result == 5) {
            gradeLetterValue = "B-";
        } else if (result == 4) {
            gradeLetterValue = "B";
        } else if (result == 3) {
            gradeLetterValue = "B+";
        } else if (result == 2) {
            gradeLetterValue = "A-";
        } else if (result == 1) {
            gradeLetterValue = "A";
        } else if (result == 0) {
            gradeLetterValue = "A+";
        }

        return gradeLetterValue;
    }

我的问题是如何使用二进制搜索获得所需结果

更新

最适合我的解决方案是创建自己的二进制搜索算法,并使用它来查找字母,例如下面的代码

public String getLetterGrade(int numerical_grade) {
        int low = 0;
        int index = count - 1;
        int max = (low + index) / 2;
        while (low < index - 1) {
            max = (low + index) / 2;
            if (this.gradeBoundary[max] <= numerical_grade)
                index = max;
            else
                low = max;
        }
        if (low == index - 1) max = low;
        return gradeLetter[max];
    }

解决方法

如果要使用Arrays.binarySearch

  1. 来自Arrays.binarySearch javadoc:

使用二进制搜索算法在指定的int数组中搜索指定的值。 必须在调用之前对数组进行排序(通过sort(int [])方法进行排序)(选择是我的选择)

Arrays.sort(int[])升序顺序对数组进行排序,因此,要使用Arrays.binarySearch,您应将gradeBoundary数组升序而不是降序。

  1. 如果您的数组中没有key,则Arrays.binarySearch返回-insertion_point - 1。插入点是一个索引,您可以在其中插入key,以便对数组进行排序。 gradeLetter数组的等级索引在插入点之前。

总而言之,此代码可以按预期工作(假设您将gradeBoundary升序排列):

// 100 is not really a boundary here so maybe we can remove it from array
private int[] gradeBoundary = {0,70,73,77,80,85,90};
private String[] gradeLetter = {"F","B-","B","B+","A-","A","A+"};

public String getLetterGrade(int numericalGrade) {
    int result = Arrays.binarySearch(gradeBoundary,numericalGrade);

    if (result < 0) {
        // (-result - 1) is an insertion point,-1 to get
        // the index of corresponding grade
        result = (-result - 1) - 1;
    }

    gradeLetterValue = gradeLetter[result];

    return gradeLetterValue;
}
,

您可以获得具有更好边界数组的边界字母等级索引,只需修改二进制搜索算法即可返回区间的上边界索引。由于当left> right时二进制搜索将不可用,因此left将是上边界的索引。如果找到键,则返回键的索引为中。因此,您只需将return -1更改为return left。并且letters[findUpperBoundaryIndex(boundaries,grade)]应该给出相应的字母等级。

int[] boundaries = {69,72,76,79,84,89,100};
String[] letters = {"F","A+"};

int findUpperBoundaryIndex(int[] arr,int key) {
    int left = 0;
    int right = arr.length - 1;
    while (left <= right) {
        int mid = left + (right-left)/2;
        if (arr[mid] == key) {
            return mid;
        }
        if (arr[mid] < key) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return left;
}

gradeLetterValue = letters[findUpperBoundaryIndex(boundaries,grade)];

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...