Java 提高字符串到二进制数转换的性能

Java 提高字符串到二进制数转换的性能,java,string,algorithm,binary,Java,String,Algorithm,Binary,这是我在竞争性编程中面临的问题之一 Ques)您有一个二进制格式的输入字符串11100,您需要计算数字为零的步数。如果数字是奇数->减去1,如果是偶数->除以2 比如说 28->28/2 14->14/2 7->7-1 6->6/2 3->3-1 2->2/2 1->1-1 0->停止 步骤数=7 我提出了以下解决方案 public int solution(String S) { // write your code in Java SE 8 String parsableSt

这是我在竞争性编程中面临的问题之一

Ques)您有一个二进制格式的输入字符串
11100
,您需要计算数字为零的步数。如果数字是
奇数->减去1
,如果是
偶数->除以2

比如说

28->28/2

14->14/2

7->7-1

6->6/2

3->3-1

2->2/2

1->1-1

0->停止

步骤数=7

我提出了以下解决方案

public int solution(String S) {
    // write your code in Java SE 8
    String parsableString = cleanString(S);
    int integer = Integer.parseInt(S, 2);
    return stepCounter(integer);
}

private static String cleanString(String S){
    int i = 0;
    while (i < S.length() && S.charAt(i) == '0')
        i++;
    StringBuffer sb = new StringBuffer(S);
    sb.replace(0,i,"");
    return sb.toString();
}

private static int stepCounter(int integer) {
    int counter = 0;
    while (integer > 0) {
        if (integer == 0)
            break;
        else {
            counter++;
            if (integer % 2 == 0)
                integer = integer / 2;
            else
                integer--;
        }
    }
    return counter;
}
public int解决方案(字符串S){
//用JavaSE8编写代码
字符串parsableString=干净字符串;
int integer=integer.parseInt(S,2);
返回步进计数器(整数);
}
私有静态字符串cleanString(字符串S){
int i=0;
而(i0){
如果(整数==0)
打破
否则{
计数器++;
如果(整数%2==0)
整数=整数/2;
其他的
整数--;
}
}
返回计数器;
}

这个问题的解决方案看起来非常简单和直接,但是这段代码的性能评估给了我一个大大的零。我最初的印象是,将字符串转换为int是一个瓶颈,但没有找到更好的解决方案。有谁能给我指出这段代码的瓶颈以及在哪里可以显著改进吗?

如果二进制数是奇数,那么最后一个(最低有效)数字必须是1,所以减去1只是将最后一个数字从1改为0(重要的是,这会使数字变为偶数)

如果二进制数是偶数,则最后一个数字必须是0,只需完全删除最后一个0,即可完成除以零的操作。(就像以10为基数一样,数字10可以除以10,去掉最后的0,留下1。)

所以每1个数字的步数是两步,每0个数字的步数是一步,减1,因为当你到达最后一个0时,你不再除以2,你只是停下来

下面是一个简单的JavaScript(而不是Java)解决方案:

let n = '11100';
n.length + n.replace(/0/g, '').length - 1;

只要再多做一点工作,就可以正确地处理前导零“0011100”(如果需要的话)。

需要减去的次数是所需的一位数。需要除法的次数是最高有效位的位置,即(32,整数中的位总数)减去1(不需要除法
1
)。对于零输入,我假设结果应该是零。所以我们有

int numberOfOperations=integer==0?0:整数。位计数(整数)+
Integer.SIZE-Integer.numberOfLeadingZeros(整数)-1;

根据给定条件,如果该数字为偶数,则将其除以2,这相当于删除LSB;如果该数字为奇数,则再次减去1,使其为偶数,这相当于取消设置位(将1更改为0)。通过分析上述过程,我们可以说所需的总步骤数将是(位数,即(log2(n)+1))和设置位数-1(最后0个不需要删除)之和

C++代码:

result=\uuuu内置的popcount(n)+log2(n)+1-1;
结果=uuu内置_upopcount(n)+log2(n)