2

My code works, but it only works for the initial cut values. I am supposed to use binary search algorithm in the getLetterGrade method to get the desired outcome but every time I do I only get the one outcome.

Spring bean class

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;
    }
}
    

Main class

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+ 

Below is my attempt with binary search and the only outcome I get is B+ when I run this code in the main program

    public String getLetterGrade(int numerical_grade) {
        int result = Arrays.binarySearch(gradeBoundary, 0, 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;
    }

My question is how can I use binary search to get the desired outcome

UPDATE

The solution that worked best for me was to create my own binary search algorithm and use it to find the letter like the code below

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];
    }

2 Answers2

1

If you want to use Arrays.binarySearch:

  1. From Arrays.binarySearch javadoc:

Searches the specified array of ints for the specified value using the binary search algorithm. The array must be sorted (as by the sort(int[]) method) prior to making this call (selection is mine)

Arrays.sort(int[]) sorts array in ascending order, so in order to use Arrays.binarySearch you should sort your gradeBoundary array ascending, not descending.

  1. If there is no key in your array then Arrays.binarySearch returns -insertion_point - 1. Insertion point is an index where you can insert your key so that your array would be still sorted. The index of grade from gradeLetter array is previous to insertion point.

To sum up, this code works as expected (assuming you sorted your gradeBoundary in ascending order):

// 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;
}
nkrivenko
  • 1,231
  • 3
  • 14
  • 23
-1

You can get letter grade index of boundary with better boundary array and simply modifying binary search algorithm to return index of upper boundary of interval. Since binary search is going to be out of while when left>right, left will be index of upper boundary. If it finds key returns key's index as mid. So you just need to change return -1 with return left. And letters[findUpperBoundaryIndex(boundaries,grade)] should give corresponding letter grade.

int[] boundaries = {69, 72, 76, 79, 84, 89, 100};
String[] letters = {"F", "B-", "B", "B+", "A-", "A", "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)];
nkrivenko
  • 1,231
  • 3
  • 14
  • 23
h4t1
  • 79
  • 1
  • 3