图片中题目的代码中位运算的部分不理解。

发布于 2022-09-06 09:45:11 字数 647 浏览 8 评论 0

图片描述

void main()
{
 int match;
 int n;
 scanf("%d", &n);

 int count = 0;
 for (int i = 0; i < (1 << n); i ++)
 {
  match = 0;
  for (int j = 0; j <= n - 3; j++)
  {
   if (((i & (7 << j)) ^ (5 << j)) == 0) // bin(7)=111; bin(5)=101
   {
    match = 1;
    break;
   }
  }
  if (match == 0)
   count ++;
 }

if (((i & (7 << j)) ^ (5 << j)) == 0) 这部分^(5<<j)这个我是理解的,比较各个位置的101.但是前面i&(7<<j)这部分猜想是2^n个10组合,但是不理解是如何得出的,在纸上硬算发现也不对头。求解答

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

ゝ偶尔ゞ 2022-09-13 09:45:11

使用7<<j保留有效的3个检查位(循环,一位一位检查),如果有则(i & (7 << j)<n-3-j个0>101<j个0>,举个例子:
n=7, i=44, j=3的场景:

i(被检查数):                00101100
7<<j:                        00111000
i & (7<<j):                  00101000
5<<j:                        00101000
((i & (7 << j)) ^ (5 << j)): 00000000 // == 0
残月升风 2022-09-13 09:45:11

提供一个更侧重数学分析的思路,可缩短运行时间至O(lg n)。记fx(n) = 长度为n的01串个数,且这些01串(1)不含101;(2)结尾为x,x=(00,01,10,11)。通过观察可以得到递推关系:

  • 以00结尾:f0(n+1) = f0(n) + f2(n)
  • 以01结尾:f1(n+1) = f0(n)
  • 以10结尾:f2(n+1) = f1(n) + f3(n)
  • 以11结尾:f3(n+1) = f1(n) + f3(n)

因此从初始值

f(2) = (f0(2), f1(2), f2(2), f3(2))' = (1, 1, 1, 1)'

通过计算矩阵乘方可以推出:

f(n) = M^(n-2) * f(2)

其中

M = 1    0    1    0
    1    0    0    0
    0    1    0    1
    0    1    0    1

耗时集中在计算M^n。用递归可以节省大量时间,比如计算M^8 = M^2^2^2,即复杂度为O(lg n)。

还可以进一步将M对角化,得到一个复对角矩阵。如果编程语言或库函数支持复数的话,甚至可将复杂度降低到O(1)。

孤凫 2022-09-13 09:45:11
void main()
{
 int match;
 int n;
 scanf("%d", &n);

 int count = 0;
 // < 1<<n  ,若n= 4,则遍历所有小于10000的数据
 for (int i = 0; i < (1 << n); i ++)
 {
  match = 0;
  // 与101 匹配,至少要三位
  for (int j = 0; j <= n - 3; j++)
  {
      // 若 满足该等式,认为匹配。 ^ 相同为0,不同为1。
      // 这里的意思就是一位一位的左移,判断您是否有匹配的,如果有匹配的就match = 1
      // 这个是在i中去三位连续数据  形如 11101 & (7 << 0)  就是  最后三位101, 11101 & (7 << 1) 就是110 ,然后与101比较。
   if (((i & (7 << j)) ^ (5 << j)) == 0) // bin(7)=111; bin(5)=101
   {
    match = 1;
    break;
   }
  }
  if (match == 0)
   count ++;
 }
世俗缘 2022-09-13 09:45:11

7的二进制为111
5的二进制为101

(i&(7<<j)) 是找到i的第j位到第j+1位上的01情况
5<<j是找到5左移j位后的01情况

(i&(7<<j))^(5<<j) 是判断i的第j位到第j+1位是不是101

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文