如何从文本文件中获取 2 个单独的数字平均值?
How to get 2 separate number averages from a text file?
我是 java 语言的新手,我不知道如何一次从文本文件中读取一行并获取该行的平均值。
到目前为止,我的工作代码获得了整个文件的平均值:
import java.util.Scanner;
import java.io.*;
public class NumAverage {
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);
File myFile = new File("Num.txt");
Scanner inputFile = new Scanner(myFile);
int numbersCounter = 0;
int sum = 0;
while (inputFile.hasNext()) {
int numList = inputFile.nextInt();
sum = sum + numList;
numbersCounter++;
}
System.out.println("Average: " + (sum/numbersCounter));
inputFile.close();
}
}
这是文本文件的样子
1 2 3 4
5 6 7 8
我认为您还必须检查“\n”(新行),
并在循环内打印平均值:
import java.util.Scanner;
import java.io.*;
public class NumAverage{
public static void main(String[] args) throws IOException{
Scanner keyboard = new Scanner(System.in);
File myFile = new File("Num.txt");
Scanner inputFile = new Scanner(myFile);
int numbersCounter = 0;
int sum = 0;
while (inputFile.hasNext())
{
if(inputFile.hasNextInt(){
int numList = inputFile.nextInt();
sum = sum + numList;
numbersCounter++;
}
if(inputFile.next().Equals("\n"){
System.out.println("Average: " + (sum/numbersCounter));
sum = 0;
numbersCounter=0;
}
}
inputFile.close();
}
}
你需要两个循环。一个遍历文件的每一行,一个遍历文件中的数字。修改您的代码以使用两个扫描仪:
package com.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestAverageFromFileLines {
public static void main(String[] args) throws FileNotFoundException {
File myFile = new File("Num.txt");
try (Scanner input = new Scanner(myFile)) {
while (input.hasNextLine()) {
String line = input.nextLine();
int numbersCounter = 0;
int sum = 0;
try (Scanner lineScanner = new Scanner(line)) {
while (lineScanner.hasNext()) {
int numList = lineScanner.nextInt();
sum = sum + numList;
numbersCounter++;
}
}
System.out.println("Average: " + ((double)sum / numbersCounter));
}
}
}
}
此外,Java 中的整数除法默认会截断小数部分。因此,要强制 Java 执行非截断除法,您需要将其中一个操作数转换为 float 或 double。
Scanner 对象有一个函数 scanner.nextLine()
它会 return 一个字符串,您可以将其处理为一系列数字,因为您知道文件的格式。
String[] myNumbersArray = myNumbers.split(" ");
for (String s : myNumbersArray) {
int myNumber = Integer.parseInt(s);
}
你必须学习 Java 的流 API(知道装饰器模式可以简化它的理解)。
针对您的情况,我们可以这样做:
FileInputStream stream = new FileInputStream("nums.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while((line = reader.readLine()) != null) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
int tokens = tokenizer.countTokens();
float average = 0;
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
int value = Integer.valueOf(token);
average += value;
}
System.out.println(average / tokens);
}
在第一行中,我创建了一个 FileInputStream
允许我们从文件中读取。
在第二行中,我将 stream
修饰为 InputStreamReader
,然后修饰为 BufferedReader
(第二行具有很好的 API 用于逐行读取输入)。
然后我逐行遍历您的文件(在循环中使用 readLine()
方法)并使用 StringTokenizer
我将行拆分为标记。
在第二个循环中,我正在做所有必要的计算。
当然你需要记住异常(为了简单起见我省略了它们)。
还有一件事值得一提 - 你需要知道在消费令牌之前应该使用 countTokens() 方法 - 否则它会 return 不正确的值(它 return这是在收到异常之前可以调用多少个 nextToken()
的数字)。
试试这个。
File myFile = new File("Num.txt");
try (Scanner c = new Scanner(myFile)) {
while (c.hasNextLine()) {
System.out.println("Average: " +
Stream.of(c.nextLine().split("\s+"))
.mapToInt(x -> Integer.parseInt(x))
.average().getAsDouble());
}
}
结果:
Average: 2.5
Average: 6.5
您可以使用 Files.lines()
创建一个文本行流,然后将每一行解析为一个数字数组并计算它们的平均值。
Files.lines(Paths.get("nums.txt"))
.map(str -> str.split(" "))
.mapToDouble(arr -> Arrays.stream(arr).mapToInt(Integer::valueOf).average().orElse(0.0))
.forEach(avg -> System.out.println("Average: " + avg));
Files.lines()
处理所有文件 I/O 并创建一个 Stream<String>
允许在从文件中读取每一行时对其进行延迟处理。如果有一天您需要处理内存中放不下的非常大的文件,这将非常有用,因为每一行只有在前一行被 Stream 完全处理后才会被读取。它会在完成后自动为您关闭文件。
下一行获取文件中的每一行并将其转换为一个字符串数组,每个数字一个。此时,流从 Stream<String>
更改为 Stream<String[]>
下一行将每个 String[] 转换为一个数字,该数字是该行数字的平均值。它通过获取字符串数组并使用 Arrays.stream()
从中创建流,使用 Integer.valueOf()
将每个字符串更改为整数,然后调用 average()
获取整个流来实现整数并计算平均值。此时 Stream 现在是 DoubleStream
.
下一行取每个平均值并打印出来。
整个操作序列发生在每一行上,因此在从文件中读取下一行之前先打印第一行的平均值。
我是 java 语言的新手,我不知道如何一次从文本文件中读取一行并获取该行的平均值。
到目前为止,我的工作代码获得了整个文件的平均值:
import java.util.Scanner;
import java.io.*;
public class NumAverage {
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);
File myFile = new File("Num.txt");
Scanner inputFile = new Scanner(myFile);
int numbersCounter = 0;
int sum = 0;
while (inputFile.hasNext()) {
int numList = inputFile.nextInt();
sum = sum + numList;
numbersCounter++;
}
System.out.println("Average: " + (sum/numbersCounter));
inputFile.close();
}
}
这是文本文件的样子
1 2 3 4
5 6 7 8
我认为您还必须检查“\n”(新行), 并在循环内打印平均值:
import java.util.Scanner;
import java.io.*;
public class NumAverage{
public static void main(String[] args) throws IOException{
Scanner keyboard = new Scanner(System.in);
File myFile = new File("Num.txt");
Scanner inputFile = new Scanner(myFile);
int numbersCounter = 0;
int sum = 0;
while (inputFile.hasNext())
{
if(inputFile.hasNextInt(){
int numList = inputFile.nextInt();
sum = sum + numList;
numbersCounter++;
}
if(inputFile.next().Equals("\n"){
System.out.println("Average: " + (sum/numbersCounter));
sum = 0;
numbersCounter=0;
}
}
inputFile.close();
} }
你需要两个循环。一个遍历文件的每一行,一个遍历文件中的数字。修改您的代码以使用两个扫描仪:
package com.test;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class TestAverageFromFileLines {
public static void main(String[] args) throws FileNotFoundException {
File myFile = new File("Num.txt");
try (Scanner input = new Scanner(myFile)) {
while (input.hasNextLine()) {
String line = input.nextLine();
int numbersCounter = 0;
int sum = 0;
try (Scanner lineScanner = new Scanner(line)) {
while (lineScanner.hasNext()) {
int numList = lineScanner.nextInt();
sum = sum + numList;
numbersCounter++;
}
}
System.out.println("Average: " + ((double)sum / numbersCounter));
}
}
}
}
此外,Java 中的整数除法默认会截断小数部分。因此,要强制 Java 执行非截断除法,您需要将其中一个操作数转换为 float 或 double。
Scanner 对象有一个函数 scanner.nextLine()
它会 return 一个字符串,您可以将其处理为一系列数字,因为您知道文件的格式。
String[] myNumbersArray = myNumbers.split(" ");
for (String s : myNumbersArray) {
int myNumber = Integer.parseInt(s);
}
你必须学习 Java 的流 API(知道装饰器模式可以简化它的理解)。
针对您的情况,我们可以这样做:
FileInputStream stream = new FileInputStream("nums.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;
while((line = reader.readLine()) != null) {
StringTokenizer tokenizer = new StringTokenizer(line, " ");
int tokens = tokenizer.countTokens();
float average = 0;
while(tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
int value = Integer.valueOf(token);
average += value;
}
System.out.println(average / tokens);
}
在第一行中,我创建了一个 FileInputStream
允许我们从文件中读取。
在第二行中,我将 stream
修饰为 InputStreamReader
,然后修饰为 BufferedReader
(第二行具有很好的 API 用于逐行读取输入)。
然后我逐行遍历您的文件(在循环中使用 readLine()
方法)并使用 StringTokenizer
我将行拆分为标记。
在第二个循环中,我正在做所有必要的计算。
当然你需要记住异常(为了简单起见我省略了它们)。
还有一件事值得一提 - 你需要知道在消费令牌之前应该使用 countTokens() 方法 - 否则它会 return 不正确的值(它 return这是在收到异常之前可以调用多少个 nextToken()
的数字)。
试试这个。
File myFile = new File("Num.txt");
try (Scanner c = new Scanner(myFile)) {
while (c.hasNextLine()) {
System.out.println("Average: " +
Stream.of(c.nextLine().split("\s+"))
.mapToInt(x -> Integer.parseInt(x))
.average().getAsDouble());
}
}
结果:
Average: 2.5
Average: 6.5
您可以使用 Files.lines()
创建一个文本行流,然后将每一行解析为一个数字数组并计算它们的平均值。
Files.lines(Paths.get("nums.txt"))
.map(str -> str.split(" "))
.mapToDouble(arr -> Arrays.stream(arr).mapToInt(Integer::valueOf).average().orElse(0.0))
.forEach(avg -> System.out.println("Average: " + avg));
Files.lines()
处理所有文件 I/O 并创建一个 Stream<String>
允许在从文件中读取每一行时对其进行延迟处理。如果有一天您需要处理内存中放不下的非常大的文件,这将非常有用,因为每一行只有在前一行被 Stream 完全处理后才会被读取。它会在完成后自动为您关闭文件。
下一行获取文件中的每一行并将其转换为一个字符串数组,每个数字一个。此时,流从 Stream<String>
更改为 Stream<String[]>
下一行将每个 String[] 转换为一个数字,该数字是该行数字的平均值。它通过获取字符串数组并使用 Arrays.stream()
从中创建流,使用 Integer.valueOf()
将每个字符串更改为整数,然后调用 average()
获取整个流来实现整数并计算平均值。此时 Stream 现在是 DoubleStream
.
下一行取每个平均值并打印出来。
整个操作序列发生在每一行上,因此在从文件中读取下一行之前先打印第一行的平均值。