找到一个数字的力量

时间:2017-01-17 15:43:33

标签: java functional-programming

我的程序要求用户输入一个2的幂(1,2,4,8..128)。此外,我必须将a[number]替换为true或false。目前,我使用switch语句来做到这一点。但是,我打算写一个能计算功率的函数。我们如何优化此代码:

switch (requested) {
    case 1:
        if (b[1] == true)
            b[1] = false;
        break;
    case 2:
        if (b[2] == true)
            b[2] = false;
        break;
    case 4:
        if (b[3] == true)
            b[3] = false;
        break;
    case 16:
        if (b[4] == true)
            b[4] = false;
        break;
    case 32:
        if (b[5] == true)
            b[5] = false;
        break;
    case 64:
        if (b[6] == true)
            b[6] = false;
        break;
    case 128:
        if (b[7] == true)
            b[7] = false;
        break;
}

4 个答案:

答案 0 :(得分:2)

您可以使用Integer中提供的功能:

int idx = Integer.numberOfTrailingZeros(requested); 
b[idx] = false;

我还会考虑验证用户输入,以确保它实际上是2的幂:

int idx = Integer.numberOfTrailingZeros(requested); 
if ((1<<idx) != requested) {
  throw new InvalidInputException(...);
}
b[idx+1] = false;

答案 1 :(得分:1)

不确定为什么你的数组索引从1开始,但我会基于此回答。

您可以计算所需的位移数量,直到0.这将为您提供正确的索引:

int index = 0; // If you want 0-based index, start this at -1.
while(requested > 0) {
    index++;
    requested >>= 1;
}
b[index] = false;

Here is a working example

警告:这会改变requested的值,如果您因任何原因需要保留原始值,请创建它的副本:int copy = requested;和请改用它。

注意:我希望内置的功能可能更合适,但我不知道它的功能是什么。

答案 2 :(得分:0)

如果您将数字与布尔值匹配,为什么不使用地图? 然后,只要用户点击足够的数字,您就可以检查并更改该值。

    //requested by user
    long requested = 16;

    //I create simply a map of powers set to true initially.
    //I presume you have something similar
    Map<Long, Boolean> powerBoolMap = new LinkedHashMap<>();
    long power = 1;
    int numberOfPowersToStore = 20;
    for (int i = 0; i < numberOfPowersToStore; i++) {
        power = power * 2;
        powerBoolMap.put(power, true);
    }

    //Then here you can just check the requested number against any 
    //key which is your 'power' and invert it or set to whatever you want.
    for (Map.Entry<Long, Boolean> e : powerBoolMap.entrySet()) {
        if (e.getKey() == requested) {
            powerBoolMap.replace(requested, !e.getValue());
        }
    }

,输出

{2=true, 4=true, 8=true, 16=false, 32=true, 64=true, 128=true, 256=true, 512=true, 1024=true, 2048=true ...}

答案 3 :(得分:0)

目前尚不清楚你的目标是什么。你说的是“计算功率”,但输入应该是一个功率(两个)。你还说你“必须将a[number]替换为真或假”而没有任何解释为什么你(想你)必须这样做。并且number应该与两个幂的指数相关联,只能从代码中猜出。

此外,您已使用“功能编程”标记了您的问题,但您的问题根本没有FP的迹象。

假设这是一个错综复杂的尝试,将一个数字分解为两个组件的幂,要表示为布尔值(相当于数字二进制表示中设置的位),你可以使用{{1 }}。 bitset在语义上已经等同于BitSet.valueOf(new long[] { requested })值的数组,当如上构造时,它已经将正确的位设置为boolean

你也可以打印它:

true

将打印

int requested = 100;
System.out.println(requested+" = "+
    BitSet.valueOf(new long[] { requested }).stream()
          .mapToObj(i -> "2^"+i).collect(Collectors.joining(" + ")));