C# 有没有一种简单的方法可以将一个整数转换为每个数字的整数数组?

C# 有没有一种简单的方法可以将一个整数转换为每个数字的整数数组?,c#,C#,说我有 var i = 987654321; 有并没有一种简单的方法来获得一个数字数组,相当于 var is = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 }; 没有.ToString()使用int.Parse(x)?public Stack NumbersIn(int-value)对字符进行加密和迭代 { 如果(值==0)返回新堆栈(); 变量编号=编号(值/10); 数字。推送(值%10); 返回号码; } 变量编号=NumbersIn(98765432

说我有

var i = 987654321;
有并没有一种简单的方法来获得一个数字数组,相当于

var is = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1 };
没有
.ToString()
使用
int.Parse(x)

public Stack NumbersIn(int-value)对字符进行加密和迭代
{
如果(值==0)返回新堆栈();
变量编号=编号(值/10);
数字。推送(值%10);
返回号码;
}
变量编号=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();
}
public int[]NumbersIn(int值)
{
变量编号=新堆栈();
对于(;值>0;值/=10)
数字。推送(值%10);
返回数字。ToArray();
}

简而言之:使用将数字除以10(%)的循环来获取提醒(每个数字)并将其放入数组。

var x=new Stack();
var x = new Stack<int>();
do
{
    x.Push(i % 10);
    i /= 10;
} while (i > 0);
return x.ToArray();
做 { x、 推(i%10); i/=10; }而(i>0); 返回x.ToArray();
另一种不使用递归且使用堆栈避免每次插入时重新分配的替代方法(至少前32位):

var列表=新堆栈(32);
var余数=123456;
做
{
列表。推送(剩余%10);
余数/=10;
}while(余数!=0);
return list.ToArray();
是的,这个方法也适用于0和负数

有趣的是,给这个算法一个负数-123456,你会得到{-1,-2,-3,-4,-5,-6}


更新:从使用列表切换到堆栈,因为这会自动给出正确的顺序。

这会转换为字符串并对字符进行迭代,但它会自动排序并以一行为单位:

var i = 987654321;
var @is = i.ToString().Select(c => c - '0').ToArray();

我知道可能有比这更好的答案,但这里有另一个版本:

您可以使用
yield return
以升序返回数字(根据重量或任何名称)

公共静态IEnumerable数字(此整数)
{
做
{
收益返回数%10;
数目/=10;
}而(数量>0);
}
12345=>5,4,3,2,1

字符串和can有趣(其他一些选项会更快…但这非常简单)

.NET 4.7.1或更高版本:

IEnumerable<long> GetDigits(long value) =>
  value == 0 ? new long[0] : GetDigits(value / 10).Append(value % 10)
IEnumerable GetDigits(长值)=>
值==0?新长[0]:GetDigits(值/10)。追加(值%10)
.NET 3.5-4.7:

IEnumerable<long> GetDigits(long value) =>
  value == 0 ? new long[0] : GetDigits(value / 10).Concat(new[] { value % 10 });
IEnumerable GetDigits(长值)=>
值==0?new long[0]:GetDigits(value/10).Concat(new[]{value%10});

刚刚对不同的方法进行了基准测试,结果如下:

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 Alloc:64 B

publicstaticint[]GetDigits(intn)
{
如果(n==0)
返回新的[]{0};
var x=数学绝对值(n);
var numDigits=NumberOfDigits(x);
var res=新整数[numDigits];
var计数=0;
而(x>0)
{
res[count++]=x%10;
x/=10;
}
数组。反向(res);
返回res;
}
公共静态整数位数(整数n)
{
如果(n>=0)
{
如果(n<10)返回1;
如果(n<100)返回2;
如果(n<1000)返回3;
如果(n<10000)返回4;
如果(n<100000)返回5;
如果(n<1000000)返回6;
如果(n<10000000)返回7;
如果(n<100000000)返回8;
如果(n<100000000)返回9;
返回10;
}
其他的
{
如果(n>-10)返回2;
如果(n>-100)返回3;
如果(n>-1000)返回4;
如果(n>-10000)返回5;
如果(n>-100000)返回6;
如果(n>-1000000)返回7;
如果(n>-10000000)返回8;
如果(n>-100000000)返回9;
如果(n>-100000000)返回10;
返回11;
}
}
共享达雷 平均值:~84.64ns 错误:1.765ns Alloc:64 B

public static int[]GetDigits\u SharedPool(int n)
{
如果(n==0)
返回新的[]{0};
var x=数学绝对值(n);
var pool=ArrayPool.Shared.Rent(11);
var计数=0;
而(x>0)
{
池[count++]=x%10;
x/=10;
}
var res=新整数[计数];
复制(池、资源、计数);
数组。反向(res);
ArrayPool.Shared.Return(池);
返回res;
}
堆栈 平均值:~89.06ns 误差:2.130ns Alloc:248 B

发件人:

public int[]堆栈()
{
var列表=新堆栈(32);
var余数=数字;
做
{
列表。推送(剩余%10);
余数/=10;
}while(余数!=0);
return list.ToArray();
}
数不清 平均值:~246.53ns 错误:4.926ns Alloc:256B

公共静态IEnumerable数字\u IEnumerable(整数)
{
做
{
收益返回数%10;
数目/=10;
}而(数量>0);
}
代码
请参见此处:

通过添加.ToArray()将列表转换为数组。我只是按照您的评论这样做:)个人偏好使用for循环,而不是do-while,以防有人怀疑。如果这是一个紧密的循环(听起来好像不是这样)在第二个版本中,你可以跳过使用列表,用对数来确定数组的大小。这是我们C类大一入门中的一个作业。n%10万岁!咳嗽成一系列的咳嗽声谢谢。更新后看起来不那么愚蠢:-)出于好奇:那有什么好处?为什么“不重复角色”?@Garry Shutler/Andrew Bullock:除了音乐参考之外?:)@Kamarey,因为这太糟糕了。@Tomalak计算支票数字是我当前的应用程序,它不起作用。首先,您将得到一个InvalidCastException。第二,int x=(int)'1';不会产生值1,但字符“1”的Unicode值为49。并且不能使用“is”作为变量名;)<选择code>is来匹配问题,但我添加了一个
@
前缀以使其合法。我总是喜欢一个很好的收益率示例,也有+1me,这就是我无法抗拒的原因!
var @is = 987654321.ToString().Select(c => c - 48).ToArray();
IEnumerable<long> GetDigits(long value) =>
  value == 0 ? new long[0] : GetDigits(value / 10).Append(value % 10)
IEnumerable<long> GetDigits(long value) =>
  value == 0 ? new long[0] : GetDigits(value / 10).Concat(new[] { value % 10 });
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 |