用代码算水费

作者: 野狗道人闯红灯 | 来源:发表于2018-04-16 12:50 被阅读7次

    故事的开始

    不知不觉在合租房中就混成了资历最老的住户,而算水费的工作也很自然的落在了我的头上。因为合租房中人员流动性很强,水费又攒了四个月没交,经过统计2017年12月到2018年3月这段时间共有11人需要交水费。于是算水费成了一件略头疼的事情。

    算水费麻烦在于大家的时间都不一样。比如之前主卧到期了,主卧有一段时间空闲,然后住进来三个人中间又走了一个人。这只是主卧的情况,其他房间也都存在这种情况。

    思路

    这件事情首先需要想清楚思路。计算水费除非给每个人安一个水表是不能达到完全公平的,那么首先假定每人每天(人/天,这个单位很重要)用的水费都是一样的。平均算水费的关键在于这一段时间里一共有多少个人/天,用总钱数除掉所有的人/天,得到的就是每人/天的钱数,然后用每个人的天数乘以每人/天的钱数就是每个人要交的水费啦~

    例子:有威尔逊和薇洛两个人合租。威尔逊住了一天,薇洛住了两天。水费一共9块,那么一共有3人/天,每人/天的水费是9/3=3,然后威尔逊的水费是31=3,薇洛的水费是32=6。

    感觉完全是小学的数学题啊,其实就是计算略麻烦,用电脑算起来稍微简单点罢了。好了,思路捋清楚了就开始动手写代码了。

    代码需要有两个输入,一是总钱数,二是每个人住的时间段。需要有一个输出是每个人要交的水费是多少。

    代码

    输入

    最开始采用了控制台的输入方式。

    private void inputFromConsole() {
        Scanner scanner = new Scanner(System.in);
        allMoney = Integer.parseInt(scanner.nextLine());
    
        String nextLine = scanner.nextLine();
        while(!nextLine.equals("0")) {
            try {
                String name = nextLine.split(" ")[0];
                String time = nextLine.split(" ")[1];
                String from = time.split(":")[0];
                String end = time.split(":")[1];
                int days = Utils.countInterval(from, end) + 1;
                System.out.println("name:" + name + ",days:" +  days);
                waterBillList.add(new WaterBill(name, time, days, null));
    
                nextLine = scanner.nextLine();
            } catch (Exception e) {
                //加一个容错,如果输入格式不对。可以重新输入。
                nextLine = scanner.nextLine();
            }
        }
    }
    

    但是控制台输入方式太费劲,还容易出错。后来就改成了从excel中读取。

    private void inputFromExcel(){
        try {
            FileInputStream inputStream = new FileInputStream(new File(excelFileName));
            //读取工作簿
            XSSFWorkbook workBook = new XSSFWorkbook(inputStream);
            //读取工作表
            XSSFSheet sheet = workBook.getSheetAt(0);
            for (int i = 1; i < sheet.getLastRowNum(); i++) {
                XSSFRow row = sheet.getRow(i);
                XSSFCell cellName = row.getCell(0);
                String name = cellName.getStringCellValue();
                XSSFCell cellTime = row.getCell(1);
                String time = cellTime.getStringCellValue();
    
                String from = time.split(":")[0];
                String end = time.split(":")[1];
                int days = Utils.countInterval(from, end) + 1;
                System.out.println("name:" + name + ",days:" +  days);
    
                XSSFCell cellDay = row.getCell(2);
                cellDay.setCellValue(days);
    
    
                waterBillList.add(new WaterBill(name, time, days, null));
            }
    
            allMoney = sheet.getRow(sheet.getLastRowNum()).getCell(1).getNumericCellValue();
    
            workBook.write(new FileOutputStream(new File(excelFileName)));
    
            inputStream.close();
            workBook.close();//最后记得关闭工作簿
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    计算

    计算其实很简单,没几行代码。总之就是先算出每人/天的钱数,然后乘以每人的天数。

    private void count() {
        int allPersonOfDay = 0;
        for (int i = 0; i < waterBillList.size(); i++) {
            allPersonOfDay += waterBillList.get(i).getDays();
        }
        double averageMoney = allMoney / allPersonOfDay;
    
        System.out.println("结果:");
    
        for (int i = 0; i < waterBillList.size(); i++) {
            String name = waterBillList.get(i).getName();
            String bill = String.format("%.2f", averageMoney * waterBillList.get(i).getDays());
            waterBillList.get(i).setBill(bill);
    
            System.out.println("名字:" + name + ",账单:" + bill);
        }
    //        createAndOutPutExcel(waterBillList);
        outPutExcel(waterBillList);
    }
    

    输出

    最后把结果输出的excel表格里,便于查看。

        private void outPutExcel(List<WaterBill> waterBills) {
            try {
                FileInputStream inputStream = new FileInputStream(new File(excelFileName));
                //读取工作簿
                XSSFWorkbook workBook = new XSSFWorkbook(inputStream);
                //读取工作表
                XSSFSheet sheet = workBook.getSheetAt(0);
    
    
                for (int i = 0; i < waterBills.size(); i++) {
                    XSSFRow row = sheet.getRow(i + 1);
                    XSSFCell cellName = row.getCell(3);
                    cellName.setCellValue(waterBills.get(i).getBill());
                }
    
                workBook.write(new FileOutputStream(new File(excelFileName)));
    
                inputStream.close();
                workBook.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    示例

    计算需要按照水费单的两个月为一个周期,下面就只使用12月和1月的水单为示例。

    首先整理一个表格把人名和对应的天数放进去。


    image

    点击运行就出来结果了。


    image

    最后

    排版可以说惨不忍睹了。这件事也算是有点意思吧,解决现实生活中的问题了。

    代码可以在这里下载 http://p06iwel4h.bkt.clouddn.com/waterBill.zip

    欢迎关注【Funny新青年】微信公众号~

    相关文章

      网友评论

        本文标题:用代码算水费

        本文链接:https://www.haomeiwen.com/subject/rhzskftx.html