说我有
var i = 987654321;
是否有一种简单的方法来获取数字数组,相当于
var is = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
没有.ToString()
并使用int.Parse(x)
迭代字符?
答案 0 :(得分:24)
public Stack<int> NumbersIn(int value)
{
if (value == 0) return new Stack<int>();
var numbers = NumbersIn(value / 10);
numbers.Push(value % 10);
return numbers;
}
var numbers = NumbersIn(987654321).ToArray();
没有递归的替代方案:
public int[] NumbersIn(int value)
{
var numbers = new Stack<int>();
for(; value > 0; value /= 10)
numbers.Push(value % 10);
return numbers.ToArray();
}
答案 1 :(得分:15)
我知道答案可能比这更好,但这是另一个版本:
您可以使用yield return
按升序返回数字(根据权重或其他任何内容)。
public static IEnumerable<int> Digits(this int number)
{
do
{
yield return number % 10;
number /= 10;
} while (number > 0);
}
12345 =&gt; 5,4,3,2,1
答案 2 :(得分:5)
另一种不使用递归并使用Stack的方法,避免在每个插入时重新分配(至少对于前32位数字):
var list = new Stack<int>(32);
var remainder = 123456;
do
{
list.Push(remainder % 10);
remainder /= 10;
} while (remainder != 0);
return list.ToArray();
是的,这种方法也适用于0和负数。
有趣的是,给这个算法一个负数-123456,你会得到{-1,-2,-3,-4,-5,-6}
更新:从使用List切换到Stack,因为这会自动给出正确的顺序。
答案 3 :(得分:4)
var x = new Stack<int>();
do
{
x.Push(i % 10);
i /= 10;
} while (i > 0);
return x.ToArray();
答案 4 :(得分:2)
简而言之:使用循环将数字模10(%)除以得到提醒(每个数字)并将其放入数组中。
答案 5 :(得分:1)
字符串并且可以很有趣(其他一些选项会更快......但这很容易)
var @is = 987654321.ToString().Select(c => c - 48).ToArray();
答案 6 :(得分:0)
.NET 4.7.1或更高版本:
IEnumerable<long> GetDigits(long value) =>
value == 0 ? new long[0] : GetDigits(value / 10).Append(value % 10)
.NET 3.5-4.7:
IEnumerable<long> GetDigits(long value) =>
value == 0 ? new long[0] : GetDigits(value / 10).Concat(new[] { value % 10 });
答案 7 :(得分:0)
只是对不同的方法进行了基准测试,结果如下:
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.19041
Intel Core i7-8705G CPU 3.10GHz (Kaby Lake G), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.301
[Host] : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
DefaultJob : .NET Core 3.1.5 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.27001), X64 RyuJIT
Method | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated |
------------------------------- |----------:|---------:|---------:|-------:|------:|------:|----------:|
Stack | 89.06 ns | 2.130 ns | 6.179 ns | 0.0592 | - | - | 248 B |
SharedArray | 84.64 ns | 1.765 ns | 3.685 ns | 0.0153 | - | - | 64 B |
PreallocateUsingNumberOfDigits | 39.15 ns | 0.861 ns | 2.499 ns | 0.0153 | - | - | 64 B |
IEnumerable | 246.53 ns | 4.926 ns | 9.372 ns | 0.0610 | - | - | 256 B |
按平均速度排序:
平均值:〜39.15ns 误差:0.861ns 分配:64 B
public static int[] GetDigits(int n)
{
if (n == 0)
return new[] {0};
var x = Math.Abs(n);
var numDigits = NumberOfDigits(x);
var res = new int[numDigits];
var count = 0;
while (x > 0)
{
res[count++] = x % 10;
x /= 10;
}
Array.Reverse(res);
return res;
}
public static int NumberOfDigits(int n)
{
if (n >= 0)
{
if (n < 10) return 1;
if (n < 100) return 2;
if (n < 1000) return 3;
if (n < 10000) return 4;
if (n < 100000) return 5;
if (n < 1000000) return 6;
if (n < 10000000) return 7;
if (n < 100000000) return 8;
if (n < 1000000000) return 9;
return 10;
}
else
{
if (n > -10) return 2;
if (n > -100) return 3;
if (n > -1000) return 4;
if (n > -10000) return 5;
if (n > -100000) return 6;
if (n > -1000000) return 7;
if (n > -10000000) return 8;
if (n > -100000000) return 9;
if (n > -1000000000) return 10;
return 11;
}
}
平均值:〜84.64ns 误差:1.765ns 分配:64 B
public static int[] GetDigits_SharedPool(int n)
{
if (n == 0)
return new[] {0};
var x = Math.Abs(n);
var pool = ArrayPool<int>.Shared.Rent(11);
var count = 0;
while (x > 0)
{
pool[count++] = x % 10;
x /= 10;
}
var res = new int[count];
Array.Copy(pool, res, count);
Array.Reverse(res);
ArrayPool<int>.Shared.Return(pool);
return res;
}
平均值:〜89.06ns 误差:2.130ns 分配:248 B
public int[] Stack()
{
var list = new Stack<int>(32);
var remainder = digit;
do
{
list.Push(remainder % 10);
remainder /= 10;
} while (remainder != 0);
return list.ToArray();
}
平均值:〜246.53ns 错误:4.926ns 分配:256 B
public static IEnumerable<int> Digits_IEnumerable(int number)
{
do
{
yield return number % 10;
number /= 10;
} while (number > 0);
}
答案 8 :(得分:-2)
这确实会转换为字符串并迭代字符,但它会自动排序并且在单行中:
var i = 987654321;
var @is = i.ToString().Select(c => c - '0').ToArray();