我有一串二进制字符,例如" 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#。
答案 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
现在说明为什么这是/不是翻转的最小数量。显示它不是最小的很容易,只是找到一种方法来翻转我的一个例子(或任何其他例子)比上面的算法更快。