用代码算水费

故事的开始

不知不觉在合租房中就混成了资历最老的住户,而算水费的工作也很自然的落在了我的头上。因为合租房中人员流动性很强,水费又攒了四个月没交,经过统计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新青年】微信公众号~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342