大多数二进制组合都是 4 位,每个位有一次变化
-
19-08-2019 - |
题
我有 4 个二进制位
Bit 3 Bit 2 Bit 1 Bit 0
通常答案很简单:2^4,即16种不同的组合;它看起来像下面这样:
0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
然而,LSB(位 0)每次迭代都会改变状态。
我需要一种算法,其中一位的状态在所有迭代中只改变一次;即,我需要所有位都像 MSB(位 3)一样工作。
我怎样才能做到这一点?
编辑
似乎大多数人都认为只有 5 种可能的解决方案。然而,这假设该值有一个起点和一个终点。这并不重要,所以我将给出一个现实世界的场景来更好地解释。
假设我有一个数字闹钟,可以提供 4 个输出。每个输出可被编程为在特定时间开启和在特定时间关闭,并且被编程为彼此独立,例如。我可以将输出 1 编程为在凌晨 1 点开启并在凌晨 3 点关闭,而我可以将输出 2 编程为在晚上 7 点开启并在凌晨 2 点关闭。每个输出可以保持多长时间没有限制。
现在我想把这个闹钟连接到电脑上,并尽可能接近当前的正确时间。例如,如果时钟显示时间为下午 2:15,我的计算机就知道闹钟在中午 12 点到下午 6 点范围内。我希望能够获得尽可能小的范围。我能得到的最小范围是多少?
解决方案
- 有 4 位。
- 每个位只能改变状态一次。
- 对于每个新值,至少有一个位必须已更改前一值的状态。
因此,最多可以有 4 次状态更改,以及最多 5 个不同的值。
例子:
0000 -> 0001 -> 0011 -> 0111 -> 1111
编辑:
很好,让我们根据您的意思而不是您所说的内容来重述。
- 有 4 位。
- 每个位只能改变状态 两次. 。(一次从0到1,一次从1到0)
- 对于每个新值,至少有一个位必须已更改前一值的状态。
因此,最多可以有 8 个状态更改,以及最多 8 个不同的值(因为最后一次状态更改必然使所有位恢复到其初始状态)
例子:
0000 -> 0001 -> 0011 -> 0111 -> 1111 -> 1110 -> 1100 -> 1000 -> 0000
因此,通过设置输出:上午 3 点 - 下午 3 点、上午 6 点 - 下午 6 点、上午 9 点 - 晚上 9 点以及中午 - 午夜,您可以从输出中确定是哪个 3 小时时段。我建议将电线插入视觉输出。
其他提示
您想格雷码。看大约一半下来“构建n位格雷码”。
我相信这是不可能的周期虽然与这样的限制的所有可能的位模式。
如果你有一个n位的想法,你可以循环但总共(N + 1),其具有翻转你已经翻转一个位之前的状态。
例如,在3位例如,如果开始时111,将得到
111
110
100
000
然后你不得不翻转一个你已经翻转得到一个新的状态。
我想你需要完成你开始对combiation,并且每一位可以在随后循环开关一次,e.g。
0000 - > 0001 - > 0011 - > 0111 - > 1111 - > 1110 - > 1100 - > 1000 - > 0000
的步骤的数量的两倍的比特数,所以用4位,你可以在3小时的范围内获得当前时间。
您想每一位只有一次改变?
像:
0000 -> 0001 -> 0011 -> 0111 -> 1111
在这种情况下,可以使用一个简单的计数器,其中所述增量被2每次迭代相乘(或左移)。
如果Gamecat正确给你, 您的位掩码值将是:
1 - 1
2 - 1
4 - 1
8 - 1
16 - 1
etc.
2^i - 1
或者,使用移位: (1 <<ⅰ) - 在0 1对于i ..
“我需要一个算法,其中位的状态只能通过所有迭代改变一次”
如果上述语句字面理解,则有每次迭代仅五个状态,如在其他职位说明。
如果问题是“有多少个可能的序列可以生成?”,则:
是对第一状态总是0000?
如果不是,那么您有16个可能的初始状态。
是否为了事?
如果是的话,你有4个! = 24种可能的方式来选择哪些位第一翻页。
因此,这提供了总共16×24 = 384个可能能够生成的序列。
在原来的问题,我想回头看我明白你的意思。
简单地最新的最小量就可以使用编程的时钟位的基础上,可能的比特组合的量
的第一个问题是需要多少序列。
60Secs×60分钟] X 24小时= 86400(所需组合) 下一步骤是找出需要多少位以产生至少86400组合
如果某人知道计算
有多少位可以产生86400种组合,那么这就是你的答案。 希望有一种式网上某处该计算
下面是你如何能保持一点距离仅被翻转一次一个例子。不知道你系统的所有参数,这是不容易给出一个准确的例子,但这里是一个无论如何。
char bits = 0x05;
flipp_bit(char bit_flip)
{
static char bits_flipped=0;
if( (bits_flipped & bit_flip) == 0)
{
bits_flipped |= bit_flip;
bits ^= bit_flip;
}
}
翻转与此功能将只允许在每个比特一个倒装。