Ради интереса я решил написать программу, которая будет рассчитывать ваш средний балл для всех возможных комбинаций оценок с учетом списка кредитных часов. Код:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.RoundingMode;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
public class GPA_Math_Testing {
public static void main(String[] args) throws IOException {
PrintWriter file = new PrintWriter("out.txt", StandardCharsets.UTF_8);
//starting points & hours
double initPoints = 131.60;
int initHours = 40;
//list of hours this semester
int[] hours = new int[]{3, 3, 3, 4, 4};
//minimum gpa to print to "filtered.txt"
double gpaMin = 3.25;
//array to store grade combinations
double[][] grades = new double[(int) Math.pow(13, hours.length)][hours.length];
//generating all possible combinations of grades
for (int i = 0; i < hours.length; i++) {
double grade = 0;
int count = 0;
for (int j = 0; j < Math.pow(13, hours.length); j++) {
grades[j][i] = grade;
count++;
if (count == (int) Math.pow(13, i)) {
grade = onePlace(incGrade(grade));
count = 0;
}
}
}
//array to store cumulative gpa
double[] totalGrades = new double[(int) Math.pow(13, hours.length)];
//calculate cumulative gpa for each combination
for (int i = 0; i < (int) Math.pow(13, hours.length); i++) {
double sum = 0;
for (int j = 0; j < hours.length; j++) {
//only time hours[i] is ever accessed
sum += grades[i][j] * hours[j];
}
totalGrades[i] = twoPlace((sum + initPoints) / (initHours + sumArr(hours)));
}
//print full list to "out.txt"
printArr(grades, totalGrades, file);
file.close();
//print combinations that reach the minimum to "filtered.txt"
PrintWriter filtered = new PrintWriter("filtered.txt", StandardCharsets.UTF_8);
try (BufferedReader br = new BufferedReader(new FileReader("out.txt"))) {
String line;
while ((line = br.readLine()) != null) {
if (Double.parseDouble(line.substring(line.indexOf('|') + 2)) >= gpaMin) {
filtered.println(line);
}
}
}
filtered.close();
}
//function to increase grade one step; wraps back from 4.0 to 0.0
public static double incGrade(double grade) {
if (onePlace(grade % 1.0) == 0.0) {
grade = onePlace(grade + 0.3);
} else if (onePlace(grade % 1.0) == 0.3) {
grade = onePlace(grade + 0.4);
} else if (onePlace(grade % 1.0) == 0.7) {
grade = onePlace(grade + 0.3);
}
if (onePlace(grade) >= 4.1) {
grade = 0.0;
}
return grade;
}
//rounding functions
public static double onePlace(double i) {
DecimalFormat onePlace = new DecimalFormat("#.#");
return Double.parseDouble(onePlace.format(i));
}
public static double twoPlace(double i) {
DecimalFormat twoPlace = new DecimalFormat("#.##");
twoPlace.setRoundingMode(RoundingMode.FLOOR);
return Double.parseDouble(twoPlace.format(i));
}
//find sum of array values
public static int sumArr(int[] a) {
int sum = 0;
for (int i : a) {
sum += i;
}
return sum;
}
//functions to print arrays
public static void printArr(double[][] a, double[] g) {
for (int j = 0; j < g.length; j++) {
for (int i = 0; i < a[j].length; i++) {
System.out.print(a[j][i] + " ");
}
System.out.print(" | " + g[j] + '\n');
}
}
public static void printArr(double[][] a, double[] g, PrintWriter file) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
file.print(a[i][j] + " ");
}
file.print(" | " + g[i] + '\n');
}
}
}
Как и сейчас, код работает отлично. Однако, если я изменю hours[]
на {3, 3, 3, 4}
или {3, 3, 4, 3}
, то out.txt
просто будет заполнен десятками тысяч бессмысленных символов.
Образец мусорного текста:
‰⸰‰⸰‰簠㈠㜮ਸ਼⸳″⸲‰⸰‰⸰‰簠㈠㜮ਸ⸳‷⸲‰⸰‰⸰‰簠㈠㠮㐊〮㈠〮〠〮〠〮†⁼⸲㈸《〮㈠㌮〠〮〠〮†⁼⸲ㄶ《㌮㈠㌮〠〮〠〮†⁼⸲㌶《㜮㈠㌮〠
Это происходит только тогда, когда initPoints = 131.60
, initHours = 40
и hours[]
равны {3, 3, 3, 4}
или {3, 3, 4, 3}
. До сих пор я не смог повторить это с любой другой комбинацией значений. Изменение sum += grades[i][j] * hours[j];
на sum += grades[i][j] * 1;
решает проблему, но я абсолютно не представляю, почему умножение на hours[j]
может вызвать это, и только с невероятно заданными c комбинациями значений. Печать на консоль вместо out.txt
дает отлично читаемый текст, и самое странное для меня то, что filtered.txt
также отлично читается, даже если out.txt
нет.
РЕДАКТИРОВАТЬ: решил попробовать вместо этого открываем нечитаемый out.txt
с помощью notepad ++, и он отображается нормально. Он также работает в Wordpad, только в Windows Notepad он отображается странно.