问题描述
我的代码有效,但仅适用于初始切割值。我应该在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
:
- 来自
Arrays.binarySearch
javadoc:
使用二进制搜索算法在指定的int数组中搜索指定的值。 必须在调用之前对数组进行排序(通过sort(int [])方法进行排序)(选择是我的选择)
Arrays.sort(int[])
以升序顺序对数组进行排序,因此,要使用Arrays.binarySearch
,您应将gradeBoundary
数组升序而不是降序。
- 如果您的数组中没有
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)];