Java 通过文本文件读取货币金额&;计算票据面额
我应该将一个文本文件读入java程序,在java文件中添加货币金额,然后确定如何支付每个总金额(读取$20、$10、$5…)。我很难解决如何将文本文件的每一行分开进行单独计算的问题 这是我要导入的文本文件:Java 通过文本文件读取货币金额&;计算票据面额,java,bufferedreader,filereader,Java,Bufferedreader,Filereader,我应该将一个文本文件读入java程序,在java文件中添加货币金额,然后确定如何支付每个总金额(读取$20、$10、$5…)。我很难解决如何将文本文件的每一行分开进行单独计算的问题 这是我要导入的文本文件: Class1 9.30 7.44 5.32 3.33 Class2 2.22 Class3 7.33 4.44 3.56 Class4 15.67 12.02 10.33 8.87 Class5 4.44 3.33 2.22
Class1 9.30 7.44 5.32 3.33
Class2 2.22
Class3 7.33 4.44 3.56
Class4 15.67 12.02 10.33 8.87
Class5 4.44 3.33 2.22 1.11
我不仅要展示每个值的解决方案,还要展示每个类的解决方案。我假设某种形式的for循环是必需的,但我无法理解
public static void main(String[] args) throws FileNotFoundException, IOException {
FileReader file = new FileReader("C:\\Users\\idhit\\Desktop\\amounts.txt");
BufferedReader bf = new BufferedReader(file);
String st = bf.readLine();
double sum = 0;
double c1total = 0;
double c2total = 0;
double c3total = 0;
double c4total = 0;
double c5total = 0;
while ((st = bf.readLine()) != null) {
StringTokenizer stn = new StringTokenizer(st);
String rn = stn.nextToken();
String name = stn.nextToken();
double c1 = Double.parseDouble(stn.nextToken());
double c2 = Double.parseDouble(stn.nextToken());
double c3 = Double.parseDouble(stn.nextToken());
double c4 = Double.parseDouble(stn.nextToken());
double c5 = Double.parseDouble(stn.nextToken());
}
double value = scan.nextDouble();
int valueIntegral = (int) value;
int valueFractional = (int) Math.round(100 * value - 100 * valueIntegral);
// Integral values
int hundred = valueIntegral / 100;
int fifty = (valueIntegral % 100) / 50;
int twenty = ((valueIntegral % 100) % 50) / 20;
int ten = (((valueIntegral % 100) % 50) % 20) / 10;
int five = ((((valueIntegral % 100) % 50) % 20) % 10) / 5;
int one = (((((valueIntegral % 100) % 50) % 20) % 10) % 5) / 1;
// Fractional values
int quarter = valueFractional / 25;
int dime = (valueFractional % 25) / 10;
int nickel = ((valueFractional % 25) % 10) / 5;
int penny = (((valueFractional % 25) % 10) % 5) / 1;
System.out.println(hundred + " hundred dollar bills\n" + fifty + " fifty dollar bills\n" + twenty
+ " twenty dollar bills\n" + ten + " ten dollar bills\n" + five + " five dollar bills\n" + one
+ " one dollar bills\n" + quarter + " quarters\n" + dime + " dimes\n" + nickel + " nickels\n" + penny
+ " pennies");
}
不过,根据名称为每个类分配总计是正确的,您需要一些条件。假设您的
bufferedReader
读取的第1行是
Class1 9.30 7.44 5.32 3.33
从StringTokenizer可以获得每个类的名称和总金额。
每次调用.nextToken()
时,它都会读取到下一个分隔符。在您的情况下,它是空白。首先.nextToken()
将读取Class1
。第二个将读取9.30
,依此类推
Class 1: 25.39
从这里开始,您可以像名字是Class1
一样将总数放入c1total
。有什么事吗?是的,你猜对了。您可以在这里使用if语句。因为有5个类,所以有5个if语句。你们的每一个while都将处理每一行,并利用if语句将其分配给正确的变量
我建议你尝试我上面写的东西,但是我用不同的方式做了同样的事情,只是为了给你一个感知,以及你如何以不同的方式编程同样的事情,甚至可能更好
编辑:像DawoodibnKareem建议的那样StringTokenizer
是遗留的,不应使用。我已经更新了密码。它现在使用拆分和,而不是双精度
// Instead of 5 variables I created an array to store data
BigDecimal[] classTotal = new BigDecimal[5];
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] lineSplit = line.split("\\s+");
// Class1 9.30 7.44 5.32 3.33 would become
// [Class1, 9.30, 7.44, 5.32, 3.33]
String name = lineSplit[0];
switch (name) {
case "Class1":
classTotal[0] = getSum(lineSplit);
break;
case "Class2":
classTotal[1] = getSum(lineSplit);
break;
case "Class3":
classTotal[2] = getSum(lineSplit);
break;
case "Class4":
classTotal[3] = getSum(lineSplit);
break;
case "Class5":
classTotal[4] = getSum(lineSplit);
break;
}
}
bufferedReader.close();
for (int i = 0; i < classTotal.length; i++) {
System.out.println("Class " + (i + 1) + " : " + classTotal[i]);
}
public static BigDecimal getSum(String[] line) {
BigDecimal sum = new BigDecimal(0);
// Iterating from index 1 because 0 index contains name
for (int i = 1; i < line.length; i++) {
BigDecimal valueBigDecimal = new BigDecimal(line[i]);
sum = sum.add(valueBigDecimal);
}
return sum;
}
输出:(如果我使用double而不是BigDecimal)
请注意某些值是如何关闭的,尤其是对于Class 4
,它应该是46.89
这是因为Java中的float和double原语类型是数字,数字存储为分数和指数的二进制表示形式。浮点数有时(可以安全地假设“大部分时间”)无法返回数字的精确表示形式。因此,您得到的是
46.88999999999
,而不是46.89
。这就是为什么在计算货币时,double/float被认为是可怕的。为了避免这个问题,我们必须使用。特别是在您的情况下,进一步对double执行计算只会使精度恶化 我回答了你的问题吗?请注意,你的valuefractal
计算可能会出现浮点错误,有时结果会太小。请检查更新答案。是的,我认为这是可行的。刚刚遇到“表达式的非法开始”。谢谢你的帮助!请注意Javadoc对StringTokenizer
类的说明-“…StringTokenizer是一个遗留类,出于兼容性原因保留了它,尽管新代码中不鼓励使用它。建议寻求此功能的任何人使用String的拆分方法或java.util.regex包……”。在这种情况下,使用扫描仪
(OP最初使用它的方式)是一个更好的选择。此外,此解决方案中的加法可能会出现浮点舍入错误,并且经常会给出错误的结果。@DawoodibnKareem您是对的。我将更新我的代码以使用更好的类,并将添加有关浮点舍入错误的信息。
。我理解您对@Goion的看法。我仍在处理输出,但感谢您的帮助!是的,那好多了。
Class 1 : 25.39
Class 2 : 2.22
Class 3 : 15.33
Class 4 : 46.89
Class 5 : 11.10
Class 1 : 25.39
Class 2 : 2.22
Class 3 : 15.33
Class 4 : 46.88999999999999
Class 5 : 11.1