前段时间,我开发了一种简单的启发式方法,它适用于我的目的。
您不仅可以计算字符串本身的 0 和 1 的“均匀性”,还可以计算字符串的导数。例如,01010101 的一阶导数是 11111111,因为每个位都在变化,二阶导数是 00000000,因为一阶导数中没有位变化。然后你只需要根据你的口味权衡这些“均匀度”。
这是一个例子:
#include <string>
#include <algorithm>
float variance(const std::string& x)
{
int zeroes = std::count(x.begin(), x.end(), '0');
float total = x.length();
float deviation = zeroes / total - 0.5f;
return deviation * deviation;
}
void derive(std::string& x)
{
char last = *x.rbegin();
for (std::string::iterator it = x.begin(); it != x.end(); ++it)
{
char current = *it;
*it = '0' + (current != last);
last = current;
}
}
float randomness(std::string x)
{
float sum = variance(x);
float weight = 1.0f;
for (int i = 1; i < 5; ++i)
{
derive(x);
weight *= 2.0f;
sum += variance(x) * weight;
}
return 1.0f / sum;
}
int main()
{
std::cout << randomness("00000000") << std::endl;
std::cout << randomness("01010101") << std::endl;
std::cout << randomness("00000101") << std::endl;
}
您的示例输入分别产生 0.129032、0.133333 和 3.2 的“随机性”。
附带说明一下,您可以通过导出字符串来获得很酷的分形图形;)
int main()
{
std::string x = "0000000000000001";
for (int i = 0; i < 16; ++i)
{
std::cout << x << std::endl;
derive(x);
}
}
0000000000000001
1000000000000001
0100000000000001
1110000000000001
0001000000000001
1001100000000001
0101010000000001
1111111000000001
0000000100000001
1000000110000001
0100000101000001
1110000111100001
0001000100010001
1001100110011001
0101010101010101
1111111111111111