7-1 水文数据校验及处理 (50 分)

**

7-1 水文数据校验及处理 (50 分)

**
使用Java中的字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算。(具体需求参见附件 2021-OO第04次作业-1指导书V1.0.pdf )

输入格式:

假定分水口门的数据上报时是采用人工输入的方式,每一行代表一个整点时刻的分水数据,各数据之间采用“|”符号进行分隔,每次可以输入多条数据,直到遇到用户输入“exit”为止,每一行输入数据共包含五部分:测量时间、目标水位、实际水位、开度(包含目标开度和实际开度,以“/”分隔)、流量。 各数据格式要求如下:

测量时间:格式为“年/月/日 时:分”,其中年份取值范围为[1,9999],“月”与“日”为一位数时之前不加“0”,日期与时间之间有一个空格,“时”与“分”之间采用冒号分隔(英文半角),“时”为一位数时之前不加“0”,“分”始终保持两位,且始终为“00”。注意:“时”数必须是24小时进制中的偶数值。
目标水位、实际水位、流量:均为实型数,取值范围为[1,1000), 小数点后保留1-3位小数或无小数(也无小数点)
目标开度、实际开度:实型数,取值范围为[1,10),必须保留2位小数,两个开度之间用“/”分隔

输出格式:

对输入的数据进行有效性校验,其规则如前所述,如遇到不符合规则的数据,系统应能够给出错误提示,提示规则如下:
如果每一行输入数据不是由“|”分隔的五部分,则输出:
Wrong Format
Data:输入的数据
如果某一部分数据有误,则按如下方式显示:
Row:行号,Column:列号Wrong Format
Data:输入的数据
其中,行号为输入数的行数(从1开始),列号为6个数据的序号(从1开始,最大为6,顺序参见输入数据结构说明)
由于人工输入数据可能存在疏忽,在每一个输入数据两端均可能存在多余的空格,程序应该能够自动过滤这些空格(不报错)。
如果用户未输入数据,则直接输出Max Actual Water Level和Total Water Flow的值即可(均为0)
若输入无误,则对数据进行如下处理:
当实际开度的值大于目标开度时,程序给出如下警告:
Row:1 GateOpening Warning
求出所输入数据中的最大实际水位值(保留2位小数),输出格式如下: Max Actual Water Level:实际水位值
根据每个整点时刻的瞬时流量求出所输入的所有时段的总流量(保留2位小数),其计算公式为(参见作业指导书):
p = ∑ n = 1 N 2 ∗ 60 ∗ 60 ∗ F l o w p = \sum_{n=1}^N2*60*60*Flow p=n=1N26060Flow
输出格式如下:

Total Water Flow:总流量值

解题报告
1.输入数据的校验一律采用正则表达式,尤其是测量日期的校验,可自行百度,一定要弄懂
2.认真研究指导书中给的类结构,思考CheckData、DealData两个类的作用
3.编写代码务必弄懂需求(指导书),务必做到严谨

输入样例1:

2015/8/2 4:00|133.8400|133.070|1.11/1.21|75.780
2015/8/2 6:00|133.840|133.080|11.11/1.11|72.8a0
2015/8/2 8:00|133.830|133.070|1.11/1.11|73.890
2015/8/2 10:00|133.820|133.080|1.11/1.11|74.380
exit

输出样例1:

Row:1,Column:2Wrong Format
Data:2015/8/2 4:00|133.8400|133.070|1.11/1.21|75.780
Row:2,Column:4Wrong Format
Row:2,Column:6Wrong Format
Data:2015/8/2 6:00|133.840|133.080|11.11/1.11|72.8a0

输入样例2:

2015/8/5 2:00|133.800|133.080|1.11/1.11|73.870
2015/8/5 4:00|133.800|133.070|1.11/1.11|73.330
2015/8/5 6:00|133.830|133.110|1.11/1.21|70.610
2015/8/5 8:00|133.860|133.140|1.11/1.11|73.430
2015/8/5 10:00|133.91|133.15|1.11/1.11|73.06
2015/8/5 12:00|133.900|133.110|1.16/1.11|75.460
2015/8/5 14:00|133.920|133.140|1.16/1.11|77.030
2015/8/5 16:00|133.92|133.16|1.16/1.91|79.4
2015/8/5 18:00|133.940|133.170|1.16/1.11|76.810
2015/8/5 20:00|133.94|133.19|1.16/1.11|74.53
2015/8/5 22:00|133.930|133.200|1.16/1.11|74.400
2015/8/6 0:00|133.930|133.200|1.16/1.11|73.150
2015/8/6 2:00|133.930|133.180|1.16/1.11|74.830
2015/8/6 4:00|133.910|133.180|1.16/1.11|    73.270
exit

输出样例2:

Row:3 GateOpening Warning
Row:8 GateOpening Warning
Max Actual Water Level:133.20
Total Water Flow:7510896.00
//有一个测试点没有通过!!!
import java.util.Scanner;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
        Scanner x = new Scanner(System.in);
        StringBuilder a=new StringBuilder(x.nextLine());//输入数据给a
        String a1=x.nextLine();
        String exit="exit";
        int i,h,flag,flag1=0;
        double sum=0,max=0;
        while (!a1.equals(exit)){
            a.append('\n').append(a1);
            a1=x.nextLine();//输入数据给a
        }
        String kp= String.valueOf(a);
        String[] b =kp.split("\n");//把输入的数据根据行放在数组b里
        Double[] sjsw =new Double[b.length];//创建实际水位的数组
        Double[] ll =new Double[b.length];//创建流量数组

        String time1= "(((([1-9])|([1-9][0-9])|([1-9][0-9]{2})|([1-9][0-9]{3})/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|(([469]|11)/([1-9]|[12][0-9]|30))|(2/([1-9]|[1][0-9]|2[0-8])))))|(((([1-9][0-9])(0[48]|[2468][048]|[13579][26]))|(([48]|[2468][048]|[3579][26])00))/2/29)) ((([02468])|(1[02468])|(2[02])):00)";//匹配时间
        String kp1="([1-9][0-9]{0,2}(\\.[0-9]{1,3})?)";//匹配水位和匹配流量
        String kdkp="([1-9]\\.[0-9]{2})";//匹配开度
        Pattern swll=Pattern.compile(kp1);
        Pattern kd1=Pattern.compile(kdkp);
        Pattern timekp=Pattern.compile(time1);

            for (i=0,h=0;i<b.length;i++){//按照行循环
                String[] hang =b[i].split("\\|");//每行通过|分隔成行数组
                String[] kd =hang[3].split("\\/");//把每行的开度通过/分开存入开度数组里

                String shijian1=hang[0].trim();//时间,去掉每一行输入的头尾的空格
                String mbsw1=hang[1].trim();//目标水位,去掉每一行输入的头尾的空格
                String sjsw1=hang[2].trim();//实际水位,去掉每一行输入的头尾的空格
                String kaidu1=hang[3].trim();//开度,去掉每一行输入的头尾的空格
                String liuliang1=hang[4].trim();//流量,去掉每一行输入的头尾的空格
                String mbkd1=kd[0].trim();//目标开度,去掉每一行输入的头尾的空格
                String sjkd1=kd[1].trim();//实际开度,去掉每一行输入的头尾的空格

                flag=0;
                if(!timekp.matcher(shijian1).matches()){//如果时间不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:1Wrong Format");
                }
                if(!swll.matcher(mbsw1).matches()){//如果目标水位不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:2Wrong Format");
                }
                if(!swll.matcher(sjsw1).matches()){//如果实际水位不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:3Wrong Format");
                }
                if(!kd1.matcher(mbkd1).matches()){//如果目标开度不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:4Wrong Format");
                }
                if(!kd1.matcher(sjkd1).matches()){//如果实际开度不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:5Wrong Format");
                }
                if(!swll.matcher(liuliang1).matches()){//如果流量不合法
                    flag=1;flag1=1;
                    System.out.println("Row:"+(i+1)+",Column:6Wrong Format");
                }

                if(flag==1){
                    System.out.println("Data:"+b[i]);
                }
                else {
                    if(Double.parseDouble(kd[0])<Double.parseDouble(kd[1])){//目标开度和实际开度相比较
                        System.out.println("Row:"+(i+1)+" GateOpening Warning");
                    }
                    sjsw[i]= Double.parseDouble(hang[2]);//把每行的实际水位的数据放入实际水位的数组里
                    ll[i]=Double.parseDouble(hang[4]);//把每行的流量的数据放入流量的数组里
                    h++;
                }
            }
            if(flag1==0){
                for(i=0;i<h;i++){//按照行循环
                    if(max<sjsw[i]){
                        max=sjsw[i];
                    }
                    sum=sum+7200*ll[i];//计算每行总流量并与之前的流量相加
                }
                System.out.printf("Max Actual Water Level:%.2f\n",max);
                System.out.printf("Total Water Flow:%.2f",sum);
            }
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VIC(Variable Infiltration Capacity)水文模型是一种广泛应用于水文研究和水资源管理的模型。为了帮助研究人员和水资源管理者更好地理解和应用VIC模型,通常会提供培训讲义和数据处理程序。 VIC水文模型培训讲义通常是由专业的水文学家和模型开发者编写的,以详细介绍VIC模型的原理、应用范围和模型参数的设置方法等内容。该讲义通常包括从基本概念到具体应用的全面介绍,帮助使用者建立对VIC模型的基本认知,并通过实例演示和实践操作,使使用者能够熟练掌握VIC模型的基本使用方法。 数据处理程序是用来处理输入数据和模型输出结果的工具。VIC模型需要输入大量的气象和地形数据,这些数据需要经过处理才能作为VIC模型的输入。数据处理程序通常提供了对气象数据处理、DEM数据处理、土地利用数据处理等功能,以便用户能够将原始数据转化为VIC模型所需的格式。同时,数据处理程序还可以帮助用户析和处理VIC模型的输出结果,以便用户能够对模型结果进行评估和应用。 总之,VIC水文模型培训讲义和数据处理程序的提供,为使用VIC模型的研究人员和水资源管理者提供了方便和支持,使他们能够更有效地利用VIC模型进行水文研究和水资源管理工作。通过培训讲义和数据处理程序的学习和应用,使用者可以更好地理解VIC模型的原理和使用方法,并能够根据具体的研究需求进行数据处理析。 ### 回答2: VIC水文模型是一种用于模拟流域水循环过程的水文模型。为了提高人们对VIC模型的理解和应用能力,进行了VIC水文模型培训,并编写了相应的讲义和数据处理程序。 VIC水文模型培训讲义是针对VIC模型的操作和应用进行详细讲解的教材。讲义包含了VIC模型的基本原理、模型结构、输入数据要求、模型参数设置等内容,并结合实例和实际应用案例进行讲解。通过讲义的学习,可以帮助学员掌握VIC模型的核心概念和操作技巧。 数据处理程序是为了方便使用VIC模型而编写的处理数据的工具。VIC模型对输入数据的要求较高,需要包括气象数据、土壤参数、水文站点信息等。数据处理程序可以帮助用户自动下载、整理和处理各类数据,并将其转换为VIC模型所需的格式和单位。通过数据处理程序,用户可以更加方便地获取和准备VIC模型所需的输入数据,提高了模型应用的效率和便捷性。 VIC水文模型培训讲义及数据处理程序的开发和应用,对于提高对VIC模型的认识和应用能力具有重要的意义。通过培训讲义的学习,可以帮助用户深入理解VIC模型的原理和运行机制,并通过实际案例进行实操操作。同时,数据处理程序的开发使得数据获取和处理更加高效和准确,为模型应用提供了良好的基础。期望通过这些工具的应用,能够提高水文模型研究的水平和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值