【发布时间】:2011-03-18 01:55:33
【问题描述】:
首先,我没有乘法、除法运算,所以我可以使用移位/加法、溢出乘法、预计算等。我只是将一个 n 位二进制数与另一个进行比较,但根据算法此类操作的数量似乎很大。这里是:
- 给定的 0 和 1 序列被分成块。假设序列的长度为 S,块的长度为 N,即为 2 的幂(4、8、16、32 等)。块的数量是 n=S/N,这里没有火箭科学。
- 根据选择的 N 我正在构建一组所有可能的 N 位二进制数,这是 2^N-1 个对象的集合。
- 在此之后,我需要将每个二进制数与源序列中的每个块进行比较,并计算每个二进制数匹配的次数,例如:
S : 000000001111111100000000111111110000000011111111...(0000000011111111 重复 6 次,16 位 x 6 = 96 位)
N : 8
块:{00000000, 11111111, 00000000, 1111111,...}
计算:
.
// _n = S/N;
// _N2 = Math.Pow(2,N)-1
// S=96, N=8, n=12, 2^N-1=255 for this specific case
// sourceEpsilons = list of blocks from input, List<string>[_n]
var X = new int[_n]; // result array of frequencies
for (var i = 0; i < X.Length; i++) X[i] = 0; // setting up
for (ulong l = 0; l <= _N2; l++) // loop from 0 to max N-bit binary number
var currentl = l.ToBinaryNumberString(_N/8); // converting counter to string, getting "current binary number as string"
var sum = 0; // quantity of currentl numbers in blocks array
for (long i = 0; i < sourceEpsilons.LongLength; i++)
{
if (currentl == sourceEpsilons[i]) sum++; // evaluations of strings, evaluation of numbers (longs) takes the same time
}
// sum is different each time, != blocks quantity
for (var j = 0; j < X.Length; j++)
if (sum - 1 == j) X[j]++; // further processing
// result : 00000000 was matched 6 times, 11111111 6 times, X[6]=2. Don't ask me why do i need this >_<
即使 S 很小,我似乎也有 (2^N-1)(S/N) 次迭代,当 N=64 时,这个数字会增长到 2^64=(long 类型的最大值),所以并不漂亮.我确信有必要优化循环并且可能从根本上改变方法(N=32 的 c# 实现需要 2h @ dual-core pc w/Parallel.For)。有什么想法可以减少上述方案的时间和资源消耗?似乎我必须预先计算二进制数并通过从文件中读取“i”来摆脱第一个循环,并用块“即时”评估它,但文件大小将是 (2^N)*N 字节(( 2^N-1)+1)*N) 这在某种程度上也是不可接受的。
【问题讨论】:
-
请对您的问题应用一些格式。它不清晰。
-
等等——你正在使用 C# 但没有乘法或除法?
-
您是否针对 Convert.ToInt64(string number, int fromBase) (msdn.microsoft.com/en-us/library/yk8t68tb.aspx) 分析了 ParseBinaryNumber 函数?
-
@Lucas Heneks 感谢您对标记的帮助。 @Billy ONeal 我在这里没有它们,就像在一些重量级的递归公式中一样。只需对大量对象进行一次简单的评估。
-
我投票结束,因为我在任何地方都看不到任何问题。我们希望能为您提供什么帮助?
标签: c# c++ algorithm optimization statistics