今天去一个公司面试的一道面试题,觉的挺有意思的,写下来做一个分享。
题目的内容如下:
有一个文本文件,统计着学生的不同时间段的成绩,现在我们需要统计出2018的所有学生的平均成绩。用你最熟悉的语言完成。
文本文件的格式如下:
首先我们看到以后,明白肯定是需要用流来,处理。但是有个问题。有很多种流,我们需要使用哪种流。
1.使用FileInputStream
伪代码
FileInputStream in=new FileInputStream(new File("D:\\test.txt"));
byte[] by=new byte[1024];
while(in.read()!=-1){
in.read(by);
}
in.close();
我们通过打印这个数组,可以看到的数据和TXT文本的数据一样,但是我们好像无法完成题目的规定。
很多人可以说,我们可以同一个一个取值,在通过字符串的拼接可以得到日期,年龄,分数等。
但是我们还要思考的问题,数据应该用哪种集合来存值。。。。。。
思考
1,数据怎么存,用什么数据结构存
2,.怎么判断是不是同一个人
3,中文名字能取到?
最终结果
肯定是不行的。就算是行也做不出来——–因为字符串拼接的时候,你根本不知道这个人的名字的长短,根本无法判断应该用哪种规律取值,拼接。只能应对一些特殊的情况。大家自己想想是不是这个道理。
还有几种错误的情况有问题,但是容易犯错了,就不列举了,直接给大家来一个终极版本
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test1 {
public static void main(String[] args) {
File file = new File("F:\\test.txt");
//保存着用户的名字,是map里面的key,用了取值
List<String> list = new ArrayList<>();
//保存着用户和用户分数,科目次数的map
Map<String, Person> map = new HashMap<String, Person>();
try {
//这个解决我们刚才说的乱码的问题,同时读取数据
FileReader re = new FileReader(file);
//用一个缓冲流,可以让我们一行行的读取,而不是全部读取
BufferedReader bu = new BufferedReader(re);
String str = "";
//读取一行
while ((str = bu.readLine()) != null) {
System.out.println(str);
Person person = new Person();
//先第一次正则拿到一行的分组
//这个方法是通用的,不管你的名字长度是多少,直接取到,不用拼接
String[] per = str.split(" ");
//第二次正则拿到时间的分组
String[] time = per[4].split("-");
if (Integer.parseInt(time[0]) == 2018) {
//这里用到一个hashMap的知识。判断key是否存在。如果存在,说明不是
//第一个存值,我们只需要更新数据就行,利用map的key存在以后,直接 覆盖值,不用删除原来的key
if (map.containsKey(per[1])) {
int sum = map.get(per[1]).getSum()
+ Integer.parseInt(per[3]);
int count = map.get(per[1]).getCount() + 1;
person.setCount(count);
person.setSum(sum);
map.put(per[1], person);
} else {
//表示第一次存值,直接存值
person.setCount(1);
person.setSum(Integer.parseInt(per[3]));
map.put(per[1], person);
//把key放入list里面,方便以后取值
list.add(per[1]);
}
}
}
//while循环完以后,我们通过list里面保留的key取值,算出平均成绩
for (String l : list) {
int arv = map.get(l).getSum() / map.get(l).getCount();
System.out.println(l + "的平均分是=" + arv);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//定义的一个javabean
//我们只需要2个属性就够了,因为-------》平均成绩=总成绩/科目数目
class Person {
int count = 1;
int sum = 0;
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public int getSum() {
return sum;
}
public void setSum(int sum) {
this.sum = sum;
}
}
哪位同学有更好的方法,可以留言,学习学习。