在本周的练习中,主要是对上周的实验进行健壮性的完善,即在所能考虑到的情况之中,尽量使自己的程序能够正常地运行。
在上周的实验中,我已经是在编程过程中考虑到用户输入的错误类型的问题,所以这一方面并没有多大的阻碍,最大的问题是没有考虑到数值的大小对最终结果的影响,所定义的存储和的变量用的是int型,这样导致了如果输入的结果过大的话,就可能导致变量的值溢出的情况,根据系统库中提供的biginteger类,提供了大数整型的处理,所以只需要对其中的int类型修改成相应的biginteger操作即可。
然后在本次练习之中要求:要对文件里面的内容进行读取再进行操作。由于考虑到健壮性,我决定在遇到类似于字符这一类数据的情况就对文件停止读取操作,根据正则表达式对其进行判断。并输出相应的错误原因。
根据上面的实现思想,我根据上周的代码修改写出了以下的代码:
package lainxu; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.math.BigInteger; import java.util.List; //import java.util.Scanner; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ShowM { //static Scanner it=new Scanner(System.in); static List<BigInteger> nums=new ArrayList<BigInteger>(); //用于储存数组 public static void main(String[] args) throws IOException { // TODO 自动生成的方法存根 List<BigInteger> max=new ArrayList<BigInteger>(); int maxp=-1; //储存从1开始的子组和最大值的位置 daochu(); if(!daoru()) { System.out.print("数据导入失败"); return; } else System.out.print("数据导入成功"); //int num=0; //手动输入区域 //-------------------------------------------- // System.out.println("请输入你想要查找数组的长度:"); // while(num<=0) //实现用户输入数组的大小 // { // if(it.hasNextInt()) // { // num=it.nextInt(); // if(num<=0) // { // System.out.println("输入数组不能小于等于0,请重新输入"); // } // // } // else // { // it.next(); // System.out.println("输入格式错误,请重新输入"); // } // } //-------------------------------------------- max.add(new BigInteger("0")); //添加一个max使其为0 for(int i=1;i<=nums.size();i++) //储存数组 { //-------------------------------------------- //手动输入区域 //System.out.println("请输入第"+i+"个数:"); BigInteger g_down=null; // while(g_down==null) // { // if(it.hasNextInt()) // { g_down=nums.get(i-1); max.add(g_down.add(max.get(i-1))); //nums.add(g_down); // } // else // { // it.next(); // System.out.println("输入格式错误,请重新输入"); // } // } //-------------------------------------------- } System.out.println("输入的数组是"+nums.toString()); BigInteger minn=max.get(0); int minp=0; BigInteger remax=max.get(1); maxp=0; for(int i=1;i<max.size();i++) { List<BigInteger> max2=max.subList(0, i); BigInteger g_min=min(max2); if(max.get(i).subtract(g_min).compareTo(remax)==1) { remax=max.get(i).subtract(g_min); maxp=i-1; minp=max.indexOf(g_min); } } System.out.println("最大子数组和为是"+(remax.subtract(minn))+",位置为("+(minp+1)+","+(maxp+1)+")"); //it.close(); } public static void daochu() throws IOException { File a=new File("suzu.txt"); FileOutputStream b = new FileOutputStream(a); OutputStreamWriter c=new OutputStreamWriter(b,"UTF-8"); for(int i=0;i<10000;i++) { int g_down=(int) (Math.random()*2000000000); if((int) (Math.random()*2)==0) { g_down=-g_down; } if(i==0) c.append(g_down+""); else c.append(" "+g_down); } c.close(); b.close(); } public static BigInteger min(List<BigInteger> max) { BigInteger g_min=max.get(0); for(BigInteger it:max) { if(g_min.compareTo(it)==1) { g_min=it; } } return g_min; } public static String change(String i) { if(i==null||i.equals("")) return null; else if(i.contains("-")) return i.replace("-", ""); else return "-"+i; } //----导入测试 @SuppressWarnings("resource") public static boolean daoru() throws IOException { File a=new File("suzu.txt"); if(!judeFileExists(a)) { System.out.println("文件不存在"); return false; } FileInputStream b = new FileInputStream(a); InputStreamReader c=new InputStreamReader(b,"UTF-8"); { BufferedReader bufr =new BufferedReader(c); String line = null; while((line = bufr.readLine())!=null){ String ook[]=line.split(" "); for(String it:ook) { if(!isNumeric(it)) { System.out.println("出现错误类型的数组,不能继续执行程序"); return false; } else { nums.add(new BigInteger(it)); } } } bufr.close(); } c.close(); b.close(); return true; } //文件判断是否存在 public static boolean judeFileExists(File file) { if (file.exists()) { return true; } else { return false; } } //判断纯数字 public static boolean isNumeric(String str) { Pattern pattern = Pattern.compile("-?[0-9]*"); if(str==null||str.equals("")) return false; Matcher isNum = pattern.matcher(str); if (!isNum.matches()) { return false; } return true; } }
接下来是对文件中9w个数的数组进行求最大子集和的结果:(16GB RAM,Window10 64位系统,i7 7700Hq下耗时半分钟之内)
这是文件里面的数据
测试其健壮性,在文件中9w条数据的任意位置插入任意错误的数据试试:
输出结果如下,能考虑到的健壮性没问题(没有文件的测试下也没有问题):