`
tea_pig
  • 浏览: 10464 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

一道阿里面试题

阅读更多

日前接到阿里一通面试电话。

有一题较为有趣,所以直接收录了下来。

需求:参照微信、支付宝红包,将金额拆分为相应人数的红包,且每个红包不得超过总金额的90%。(由于都是在电话里口述,不知道有没有听错需求,姑且就当它是正确的吧)

 

由于该需求会产生较多0.01的红包,但是暂且不论红包金额的算法,只论生成红包这段代码是否有错,望大神提点。

 

package com.demo;

import java.math.BigDecimal;
import java.util.Random;

public class Demo {

    /**
     * 单元测试
     */
    @org.junit.Test
    public void testSplitRedPacket() throws Exception {
        long startTime = System.currentTimeMillis();
        int sum = 0;
        BigDecimal amount;
        int pCount = 2;

        for (double i = 1; i < 10;) {
            sum = 0;
            amount = new BigDecimal(String.valueOf(i));
            int amountInt = amount.multiply(new BigDecimal("100")).intValue();

            int[] packets = splitRedPacket(amountInt, pCount);
            for (int packet : packets) {
                sum += packet;
            }
            BigDecimal bSum = new BigDecimal(Double.valueOf(sum / 100.0));

            assertCompare(bSum, amount);

            if(pCount < 20) {
                pCount++;
            } else {
                pCount = 2;
            }
            i = new BigDecimal(String.valueOf(i)).add(new BigDecimal("0.1")).doubleValue();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("总消耗时间:" + (endTime - startTime) + "毫秒");
    }

    private void assertCompare(BigDecimal sum, BigDecimal amount) {
        // System.out.println(sum.doubleValue() + " " + amount.doubleValue());
        if(sum.doubleValue() != amount.doubleValue()) {
            throw new RuntimeException("拆分后总金额不相等,计算出错\nbd1=" + sum.doubleValue() + " bd2=" + amount.doubleValue());
        }
    }

    /**
     * 拆分红包
     * 
     * @param amount 总金额
     * @param pCount 人数
     * @return
     * @throws Exception
     */
    public int[] splitRedPacket(int amount, int pCount) throws Exception {

        // 总金额
        /*
         * TODO 总金额直接使用分计算
         */
        // 先将总金额单位改为分
        int amountInt = amount;

        // 验证最小红包金额
        verifyMinPacket(amountInt, pCount);

        int[] redPackets = new int[ pCount ];

        Random r = new Random(System.nanoTime());
        // 最大红包金额
        int max = amountInt;
        // 已发放总金额
        int sum = 0;
        // 每份的金额
        int part = 0;

        for (int i = 0; i < pCount - 1; i++) {
            // 预留金额
            int preAmount = preAmount(max, amountInt, pCount - i - 1);
            max -= preAmount;

            part = r.nextInt(max) + 1;

            // 余额
            max -= part;

            // 补偿预留金额
            max += preAmount;

            sum += part;
            // BigDecimal bPart = new BigDecimal(Double.valueOf(part / 100.0));
            redPackets[i] = part;

        }
        // 最后一份红包
        // redPackets[pCount - 1] = new BigDecimal(Double.valueOf((amountInt - sum) / 100.0));
        redPackets[pCount - 1] = amountInt - sum;
        return redPackets;
    }

    /**
     * 计算预留金额
     * 
     * @param balance 余额
     * @param amount 总金额
     * @param pCount 剩余人数
     * @return
     */
    private int preAmount(int balance, int amount, int pCount) {
        // 打9折
        int $9 = (int) (amount * 0.9);
        if(balance > $9) {
            // 余额必须大于总金额的90% 并且 10%足够剩余人数分
            int $1 = (int) (amount * 0.1);
            if($1 / pCount >= 1) {
                return $1;

            } else {
                // 10%不够分的时候
                return pCount;
            }
        }
        return pCount;
    }

    /**
     * 验证最小红包金额
     * 
     * @param amount 总金额
     * @param pCount 人数
     * @return
     * @throws Exception
     */
    private boolean verifyMinPacket(int amount, int pCount) throws Exception {
        if(amount / pCount >= 1) {
            return true;
        }
        throw new Exception("单个红包不能小于0.01");
    }

}

 

分享到:
评论

相关推荐

    os论文 关于阿里面试题的解析

    ### os论文 关于阿里面试题的解析 #### 一、问题背景与初步分析 本篇文章主要探讨了一道来自阿里巴巴的面试题目,该题目涉及到C语言的递归函数及其运行时间的分析。题目给出的递归函数如下: ```c int f(int x){ ...

    选择文件 ( 阿里研发面试题2016最新.docx )

    总结起来,本文介绍了进程创建的基本概念,特别是`fork()`函数的工作方式,以及正则表达式的使用和匹配规则,同时涉及了一道逻辑推理题。对于研发面试来说,这些知识点涵盖了操作系统、编程基础和逻辑思维能力,都是...

    阿里各岗位技术面试题含答案最新.docx

    【阿里技术面试题解析】 1. **SynchronousQueue Quiz** SynchronousQueue 是一个特殊的 BlockingQueue,它不存储任何元素,所有的插入操作必须等到其他线程进行相应的删除操作才能完成。在给定的代码中,试图向空...

    2023最新版大厂面试真题

    在IT行业中,面试是每个求职者必经的重要环节,尤其是对于目标锁定在知名大厂的求职者来说,准备充分的面试至关...同时,对比不同公司的面试题,还可以了解各家公司对人才的不同需求和偏好,进一步优化自己的面试策略。

    2012十月百度_阿里巴巴_迅雷_搜狗面试题

    以下是针对这些面试题的详细解析: 1. 找到指定坐标的结构:对于这个问题,可以考虑使用哈希表,将每个结构的坐标作为键,结构本身作为值,这样可以实现常数时间内的查找。 2. 求未出现的数:可以使用布隆过滤器,...

    阿里技术《程序员面试宝典》

    这本书不仅提供了解题思路,还对每一道题目的不同解法进行了详尽的解析,有的题目甚至给出了多种解法,帮助读者开阔思维,理解算法的多样性。通过这些内容的学习,读者能够提升解决实际问题的能力,增加面试成功的...

    阿里巴巴面试题leetcode-CharSimpleAlgorithm:字符串算法

    阿里巴巴面试题leetcode CharSimpleAlgorithm 字符串算法 WordConversion 该类是用于改变字母的大小写,使一...ps:该类的实际意义没有想到,是我在浏览LeetCode评论区的时候看到的一道阿里巴巴面试题,所以就实现了一下

    高中数学如何解决阿里面试算法题

    今天跟大家分享一道阿里的算法面试题。 题目描述 给定一个正整数nnn,把它拆分为若干个数的和,记这若干个数的积为MMM,求MMM的最大值。 题目分析 这道题正常的思路是使用动态规划算法。 假设 dp[n]dp[n]dp[n] 为正...

    类实例化顺序讲解 附阿里巴巴一道笔试题

    以下是对类实例化顺序的详细讲解,以及阿里巴巴笔试题的解析。 首先,类加载分为三个主要阶段:加载、链接和初始化。 1. **加载**:这是类被首次引用时,JVM会尝试从类路径中找到对应的`.class`文件,并将其加载到...

    c代码-据说是阿里的一道面试题。请说出运行结果。答案是无限循环

    这段C语言代码是一道经典的面试题,主要考察的是对指针和循环的理解。题目中提到“答案是无限循环”,这提示我们代码中可能存在一个没有明确退出条件的循环结构。让我们来详细分析一下。 首先,我们需要查看`main.c...

    阿里巴巴笔试题打包

    对于那些渴望成为“阿里人”的求职者而言,笔试环节无疑是一道难以逾越的高墙。为了一窥阿里巴巴笔试题的奥秘,我们将深入解析可能涉及的知识点以及如何准备应对此类挑战。 首先,回顾2009年9月在南京进行的阿里...

    华为od社招python开发面试题.docx

    3. **算法题解答**:技术面试环节通常会有一道算法题,需在规定时间内完成。 - 建议策略:先快速理解题目要求,再构思解题思路,最后编码实现。 4. **沟通技巧**: - 在面试过程中保持自信,即使遇到不懂的问题也...

    华为od社招python开发面试题.pdf

    3. **实战演练**:面试中可能会给出一道算法题供现场解答,通常时间为20分钟左右。 - **建议**:提前熟悉常见的数据结构与算法,提高解决问题的能力。 #### 六、综合建议 1. **技术积累**:不断学习新知识,提高...

    dp.cpp — 阿里2015校招的一道题

    一个合法的表达式由()包围,()可以嵌套和连接,如(())()也是合法表达式;现在有6对(),它们可以组成的合法表达式的个数为多少?

    最新阿里算法(LeetCode)指南(文档和代码).zip

    4. 面试题解析:涵盖LeetCode上的经典题目,分析解题思路和最优解法; 5. 实战经验:分享阿里巴巴内部项目中的算法应用,以及面试过程中可能遇到的问题。 三、代码示例 配套的代码示例通常会以Python、Java、C++等...

    阿里巴巴2014校园招聘笔试试题-软件研发工程+网友版答案.docx

    - 第19题:这是一道关于组合计数的问题,询问的是在一定条件下不同颜色球的组合数。 4. **系统负载与性能监控**: - 第22题:题目涉及系统负载的概念,指出了一分钟、五分钟和十五分钟的平均负载,负载越低说明...

    阿里巴巴校园招聘笔试试题(java).doc

    1. **逻辑推理**:这些题目属于逻辑推理题,常见于面试和笔试中,用于测试应聘者的逻辑思维能力。例如Question 1、2、4、5、7、8、9都是关于逻辑推理的题目。Question 1中,肯尼迪的讲话基于美国石油公司应该听从...

Global site tag (gtag.js) - Google Analytics