我正在尝试计算数字序列中每个数字的数字乘积,例如:
21、22、23……98、99……
将会:
2, 4, 6 ... 72, 81 ..
为了降低复杂性,我会只考虑有限长度数字中的 [连续数字],例如 from 001
to999
或 from 0001
to 9999
。
但是,例如,当序列很大时1000000000
,重复提取数字然后对每个数字相乘将是低效的。
基本思想是跳过我们在计算过程中遇到的连续零,例如:
using System.Collections.Generic;
using System.Linq;
using System;
// note the digit product is not given with the iteration
// we would need to provide a delegate for the calculation
public static partial class NumericExtensions {
public static void NumberIteration(
this int value, Action<int, int[]> delg, int radix=10) {
var digits=DigitIterator(value, radix).ToArray();
var last=digits.Length-1;
var emptyArray=new int[] { };
var pow=(Func<int, int, int>)((x, y) => (int)Math.Pow(x, 1+y));
var weights=Enumerable.Repeat(radix, last-1).Select(pow).ToArray();
for(int complement=radix-1, i=value, j=i; i>0; i-=1)
if(i>j)
delg(i, emptyArray);
else if(0==digits[0]) {
delg(i, emptyArray);
var k=0;
for(; k<last&&0==digits[k]; k+=1)
;
var y=(digits[k]-=1);
if(last==k||0!=y) {
if(0==y) { // implied last==k
digits=new int[last];
last-=1;
}
for(; k-->0; digits[k]=complement)
;
}
else {
j=i-weights[k-1];
}
}
else {
// receives digits of a number which doesn't contain zeros
delg(i, digits);
digits[0]-=1;
}
delg(0, emptyArray);
}
static IEnumerable<int> DigitIterator(int value, int radix) {
if(-2<radix&&radix<2)
radix=radix<0?-2:2;
for(int remainder; 0!=value; ) {
value=Math.DivRem(value, radix, out remainder);
yield return remainder;
}
}
}
此处仅用于数字的枚举,为避免包含零的数字首先被计算,数字乘积尚未由代码给出;但是通过提供委托来执行计算来生成数字产品仍然需要时间。
如何有效地计算连续数字的数字积?