任务内容:
任务思路:
我们在上次对文本数据进行提取之后,这次主要就是对提取的数据进行相应的操作,将参数代入我们已知的公式当中即可。
公式:
参数:
任务执行:
1.尝试提取数据计算
就像上篇提到的问题:如果始终将数组的输出放在while循环体内部,我们就没有办法提取出整列的数据来进行我们的数据运算,所以我们对上篇的代码进行一点小小的修改:
String line;
String filename = "/E:/Desktop/Study/JAVA/Curri design/well_logging_data.txt";
// 用于存储每行数据的列表
List<double[]> dataList = new ArrayList<>();
double[] db = new double[0];
FileReader fr = new FileReader(filename);
BufferedReader bfr = new BufferedReader(fr);
int lines = 1;
for (int i = 0; i < 7; i++) {
bfr.readLine();
}
System.out.println(lines);
while ((line = bfr.readLine()) != null) {
//split的正则化表达,可以处理多个非整型浮点型字符,如空格
String[] st = line.split("\\s+");
db = new double[st.length];
for (int i = 0; i < st.length; i++) {
try {
db[i] = Double.parseDouble(st[i]);
} catch (NumberFormatException e) {
System.out.println("无效的输入: " + st[i]);
}
}
dataList.add(db); // 将当前行数据添加到列表中
}
double[][] tm = new double[dataList.size()][];
for (int i = 0; i < dataList.size(); i++) {
tm[i] = dataList.get(i);
}
我们与上次这部分的代码进行对比:
String line;
String filename = "/E:/Desktop/Study/JAVA/Curri design/well_logging_data.txt";
FileReader fr = new FileReader(filename);
BufferedReader bfr = new BufferedReader(fr);
for (int i = 0; i < 7; i++) {
bfr.readLine();
}
while ((line = bfr.readLine()) != null) {
//split的正则化表达,可以处理多个非整型浮点型字符,如空格
String[] st = line.split("\\s+");
double[] db = new double[st.length];
for (int i = 0; i < st.length; i++) {
try {
db[i] = Double.parseDouble(st[i]) + 2;
} catch (NumberFormatException e) {
System.out.println("无效的输入: " + st[i]);
continue;
}
}
System.out.println(Arrays.toString(formatArray(db)));
}
可以看到我们在开头多了一段语句:List<double[]> dataList = new ArrayList<>();
这句话是什么意思呢?——
1.List<double[]>是一个泛型类型,表示一个元素类型为 double 数组的列表。也就是说,dataList 是一个列表,其中的每个元素都是一个 double 类型的数组。
2.ArrayList<>是 Java 中的一个类,实现了 List 接口,用于表示动态数组。在这里,通过 new ArrayList<>() 创建了一个新的 ArrayList 实例,该实例可以存储 double 类型的数组。
因此,整个语句的含义是:声明并实例化了一个名为 dataList 的列表,其中每个元素都是 double 类型的数组。
double[][] tm = new double[dataList.size()][];
for (int i = 0; i < dataList.size(); i++) {
tm[i] = dataList.get(i);
}
对于上面这段代码,就是创建了一个二维数组tm,将dataList中的每一个一维数组放到tm中:
1.double[][] tm = new double[dataList.size()][]; 这行代码声明并实例化了一个二维数组 tm,其中包含的行数与 dataList 中元素的数量相同。每一行都是一个 double 类型的一维数组。但是,由于还没有为每一行分配具体的数组,所以每个数组元素的列数暂时为空。
2.紧接着是一个循环,从 dataList 中获取每个 double 类型的数组,并将其赋值给 tm 数组的相应行。循环的迭代变量 i 从0开始,直到 dataList 的大小减1。在每次迭代中,tm[i] 将被赋值为 dataList.get(i),即取出 dataList 中第 i 个元素,这个元素本身就是一个 double 类型的数组。
2.定义公式方法
//孔隙度计算
public static Double porosity(double DT) {
double DTf = 189.0000;
double DTma = 88.0;
double POR = (DT - DTma) / (DTf - DTma);
return POR;
}
//泥质含量计算
public static Double shale(double GR) {
double GCUR = 3.7000;
double GRmx = 156.0010;
double GRmn = 52.2120;
double SH;
SH = (GR - GRmn) / (GRmx - GRmn);
double VSH = (Math.pow(2,GCUR * SH) - 1)/(Math.pow(2,GCUR) - 1);
return VSH;
}
//含油饱和度计算
public static Double oil(double LLD, double POR) {
double Rw = 0.0400;
double a = 0.6600;
double b = 1.0000;
double m = 1.6496;
int n = 2;
double sw = Math.pow((a * b * Rw) / ((Math.pow(POR, m)) * LLD), 0.5);
double So = 1 - sw;
return So;
}
按照上面的公式定义了三个计算方法,其实这里也可以用到子类调用父类的写法,实现我们方法的重写,就不用重复写一些内容,但是我掌握的不是很好哈哈哈哈。
3.简易菜单实现用户交互
System.out.println("请输入想要读取第几行数据:");
Scanner sc = new Scanner(System.in);
int row = sc.nextInt();
System.out.println("please choose ->>");
System.out.println("********0. 孔隙度 ********");
System.out.println("********1. 泥质含量 ********");
System.out.println("********2.含油饱和度********");
System.out.println("********3.all output*******");
Scanner num = new Scanner(System.in);
int n = num.nextInt();
switch (n){
case 0:
System.out.println("孔隙度为:");
System.out.println(porosity(tm[row][2]));
break;
case 1:
System.out.println("泥质含量为:");
System.out.println(shale(tm[row][3]));
break;
case 2:
System.out.println("含油饱和度为:");
System.out.println(oil(tm[row][4], porosity(tm[row][2])));
break;
case 3:
System.out.println("孔隙度为:");
System.out.println(porosity(tm[row][2]));
System.out.println("泥质含量为:");
System.out.println(shale(tm[row][3]));
System.out.println("含油饱和度为:");
System.out.println(oil(tm[row][4], porosity(tm[row][2])));
break;
default:
System.out.println("输入有误");
break;
}
菜单的实现还是比较简单,就不多赘述了~
小结
今天我们解决了之前不方便调用读取数据的问题,主要就是把它放到一个二维数组当中为我们所用,因为二维数组对于行和列的调用真的很方便。具体可以多多研究一下Java中列表的相关知识,还是比较高级~
今天的内容就到这里啦,希望对你有一丢丢的帮助就好~