将二进制数字流转换为全部1#s

时间:2016-04-09 14:41:00

标签: algorithm

我有一串二进制字符,例如" 10101"。我需要把它转换成所有的1。我需要转换它的方法是使用下面的方法,将0到j之间的字符串反转,然后将每个字符从0转换为j索引。

void ReverseAndFlip(string &str, int j)
{
    int i=0;
    while(i<j)
    {
        char temp = str[i];
        str[i++]=str[j];
        str[j--]=temp;
    }
    for(int k=0;k<=j;k++)
    {
        if(str[k]=='0')
            str[k] = '1';
        else
            str[k]=='0';
    }
}

我需要确定ReverseAndFlip函数所需的最小调用次数,以便将二进制字符串转换为所有1#。

1 个答案:

答案 0 :(得分:0)

我认为只是解决问题的算法并不简单,所以我会在这里发布一个算法,尽管它确实没有完全回答这个问题。我即将展示的最低限度尚未确定,但我可以保证我们最多需要n个步骤来获得长度为n的二进制字。

这里的诀窍是我们真的只能操纵单词前面的位,而不是后面的位。这意味着我们应该做一些“前线”分组。所以,我的算法如下。从单词的前面开始查找一致数字(1或0)的最大子字符串。然后翻转所有这些位(请注意,如果它们全部相同,则翻转和反转与翻转相同)。然后,重复这个过程,直到我们全部为1。

示例:

 |      j=1   ||     j=2   |||    j=3   ||||   j=4
"10101" ---> "00101" ---> "11101" ---> "00001" ---> "11111"

另一个例子:

 ||          j=1   ||||        j=2   |||||       j=3   |||||| 
"0011010111" ---> "1111010111" ---> "0000010111" ---> "1111110111" 

j=4   |||||||     j=5
---> "0000000111" ---> "1111111111"

所以,这个算法在我们拥有的“翻转”中运行,如果单词以0结尾,则加上一个。因此,“10101”有4个翻转(“1x0x1x0x1”),因为每个位翻转,我们结束一个人。因此,总翻了4次。 “0011010111”有5次翻转(“00x11x0x1x0x111”)。如果数字末尾有一个0,我们有一个奖金翻转。例如,“11001010”具有(“11x00x1x0x1x0x”)6翻转,因为最后一个数字是0,所以最后一步只是将所有0翻转为1。像这样:

         j=1           j=2           j=3           j=4
11001010 ---> 00001010 ---> 11111010 ---> 00000010 ---> 11111110

j=5           j=6
---> 00000000 ---> 11111111

现在说明为什么这是/不是翻转的最小数量。显示它不是最小的很容易,只是找到一种方法来翻转我的一个例子(或任何其他例子)比上面的算法更快。