众所周知,任何整数都可以通过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;
}
}