周期性二进制表示

时间:2014-04-12 09:23:02

标签: c++ algorithm binary period

如何创建一个程序来检查给定整数的二进制表示是否是周期长度为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 ++工作。

2 个答案:

答案 0 :(得分:0)

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 page或相关的教科书,例如“算法简介”。

答案 1 :(得分:0)

您可以做的是旋转位并每次检查数字是否相等。即旋转的那个和你开始的那个

// 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";

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