周期性二进制表示

Periodical binary representation

本文关键字:表示 二进制 周期性      更新时间:2023-10-16

如何制作一个程序来检查给定整数的二进制表示是否是周期长度m>=2的周期性?

例如:

10的二进制表示是周期性

10 base 10 = 1010 base 2, periodical with period length 2

9的二进制表示不是周期性

9 base 10 = 1001 base 2

153的二进制表示是周期性

153 base 10 = 10011001 base 2, periodical with period length 4

有什么具体的算法可以做到这一点吗?

我在C++中工作。

您可以做的是旋转位,每次检查数字是否相等。即旋转的和您从开始的

// it is being assumed the size of int is 4bytes
int num = 153;
int temp = num;
int i = 0;
for (i=0; i<(8*sizeof(int))/2; i++){
    temp = ((temp >> 1) & LONG_MAX | temp << 31) // rotate the bits by 1
    if (!(temp ^ num)){ // check if the numbers are the same
        break;
    }
}
if (i<(8*sizeof(int))/2)
    std::cout << "Period is" << i << "n";
else
    std::cout << "Not periodic";

复杂度在位数上是线性的。

KMP是一种特定的算法,用于查找任何字符串的句点,包括数字的二进制表示,它只是一个字符串。它在O(n)时间内运行。

#include <iostream>
#include <algorithm>
using namespace std;
int calc_period(string s) {
  vector<int> pre(s.size());
  // this condition is keeped true in the for-loop:
  //    s[0..pre[i]] is this longest suffix of s[0..i] in s[0..i]'s all prefixes (if pre[i] >= 0)
  int k = -1;
  pre[0] = -1;
  for (int i = 1; i < int(s.size()); ++i) {
    while (k >= 0 && s[k + 1] != s[i]) {
      k = pre[k];
    }
    if (s[k + 1] == s[i]) {
      ++k;
    }
    pre[i] = k;
  }
  int l = s.size() - 1 - pre[s.size() - 1];
  return s.size() % l == 0 ? s.size() / l : 1;
}
string to_binary(long long x) {
  string s;
  if (x == 0) {
    s = "0";
  } else {
    while (x) {
      s += (x & 1) ? "1" : "0";
      x >>= 1;
    }
    reverse(s.begin(), s.end());
  }
  return s;
}
int main() {
  int x;
  cin >> x;
  cout << calc_period(to_binary(x)) << endl;
  return 0;
}

您可以尝试一下这段代码,看看它是如何工作的。如果你想更深入地了解KMP,可以阅读它的wiki页面或相关的教科书,如"算法简介"。