如何创建一个程序来检查给定整数的二进制表示是否是周期长度为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 ++工作。
答案 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";
复杂度在位数上是线性的。