当我需要从数字的各位数位计算出校验码/数字时,我遇到了这个挑战。
例如,我有一个数字(Int32
):423594340
,我想要一个包含整数4,2,3,5,9,4,3,0
的集合。
我认为最好不要将给定的int
转换为String
,因为这会影响性能。那么你该怎么做呢?
当我需要从数字的各位数位计算出校验码/数字时,我遇到了这个挑战。
例如,我有一个数字(Int32
):423594340
,我想要一个包含整数4,2,3,5,9,4,3,0
的集合。
我认为最好不要将给定的int
转换为String
,因为这会影响性能。那么你该怎么做呢?
我想出了一个个人难题解决方案。
public static IEnumerable<int> GetDigits(int source)
{
int individualFactor = 0;
int tennerFactor = Convert.ToInt32(Math.Pow(10, source.ToString().Length));
do
{
source -= tennerFactor * individualFactor;
tennerFactor /= 10;
individualFactor = source / tennerFactor;
yield return individualFactor;
} while (tennerFactor > 1);
}
在尝试了其他方法后,我在网上找到了来自Java社区的一个解决方案:如何获取int数字的各个数字?
缺点是,集合中的整数顺序被反转了。这时候就需要使用微软的Linq了。
使用.Reverse()
方法调用该方法。
...
GetDigits2(input).Reverse()
...
实际的方法。
public static IEnumerable<int> GetDigits2(int source)
{
while (source > 0)
{
var digit = source % 10;
source /= 10;
yield return digit;
}
}
当我在使用GetDigits2(int source)
方法后不想再考虑调用.Reverse()
方法时,我还能做什么呢?所以我在方法内部使用一个变量,在变量上调用了.Reverse()
方法,并返回其结果。
或者完全不同的做法:我记得LIFO逻辑。在.NET中,您可以使用Stack类实现它。
public static IEnumerable<int> GetDigits3(int source)
{
Stack<int> digits = new Stack<int>();
while (source > 0)
{
var digit = source % 10;
source /= 10;
digits.Push(digit);
}
return digits;
}
我对每种方法进行了1000万次测试,并测量了测试开始和结束之间的时间差。
#1:自己创建的方法
1'549'084 ticks
#2: 使用Linq的.Reverse()进行模数计算
2'252'875 ticks
#3:使用堆栈LIFO取模
23'626'839 ticks
简短概述:
这里有一个fiddle示例:从int中获取数字