分解整数小游戏

        众所周知,任何整数都可以通过2的几次方的和的方式来组成,如11是8+2+1组成的,100是64+32+4,其组合是唯一的。如果将表单的id设为2的几次方的形式,那么保存用户勾选的id的和即可分解出是勾选的哪几项。如下:

package com.example.simple.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


public class test3 {

    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(System.in);
            Long a = 0L;
            System.out.println("请输入一个正整数:");
            while ((a = scanner.nextLong()) > 0){
                toDo(a);
                System.out.println("请输入一个正整数:");
            }
            if (a <= 0 || a > 4611686018427387904L){
                throw new RuntimeException();
            }
        }catch (Exception e){
            System.err.println("您的输入有误!");
        }

    }

    private static void toDo(Long a){
        // 1、找到最大幂
        Long b = getMax(a);
        // 2、得到最大幂的值
        Long maxItem = 1L << b;
        // 3、循环比较得到其他部分
        List<Long> result = getItems(a, b, maxItem);
        // 4、输出
        System.out.println("\t该正整数的组成成分为: " + result);
    }


    /**
     * 获取最大部分值
     * @param a
     * @return
     */
    private static Long getMax(Long a){
        for(Long i = 0L; i < 63; i++){
            Long A = 1L << i;
            if (a < A){
                return i - 1;
            }else if(a.equals(A)){
                return i;
            }
        }
        return null;
    }

    /**
     * 获取其余部分
     * @param a 最终结果值
     * @param b 最大幂
     * @param maxItem 最大部分值
     * @return
     */
    private static List<Long> getItems(Long a, Long b, Long maxItem){
        List<Long> resultArr = new ArrayList();
        resultArr.add(maxItem);
        if(a.equals(maxItem)){
            return resultArr;
        }
        do{
            Long c = 1L << (b-1);
            if (maxItem + c <= a){
                resultArr.add(c);
                maxItem += c;
                b -= 1L;
            }else {
                b -= 1L;
                continue;
            }
        }while (!maxItem.equals(a) && b >= 0);
        return resultArr;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值