如何获得int(C#)中的第一个数字?

Din*_*nah 77 c#

在C#中,获取int中第一个数字的最佳方法是什么?我想出的方法是将int转换为字符串,找到字符串的第一个字符,然后将其转回int.

int start = Convert.ToInt32(curr.ToString().Substring(0, 1));
Run Code Online (Sandbox Code Playgroud)

虽然这可以完成这项工作,但感觉可能是一个很好的,简单的,基于数学的解决方案来解决这个问题.字符串操作感觉很笨重.

编辑:无论速度差异如何,mystring [0]而不是Substring()仍然只是字符串操作

Joh*_*sch 213

基准

首先,您必须决定"最佳"解决方案的含义,当然这要考虑算法的效率,可读性/可维护性以及未来出现错误的可能性.但是,仔细的单元测试通常可以避免这些问题.

我运行了这些示例中的每一个1000万次,结果值是ElapsedTicks已经过的数量.

没有进一步的麻烦,从最慢到最快,算法是:

转换为字符串,取第一个字符

int firstDigit = (int)(Value.ToString()[0]) - 48;
Run Code Online (Sandbox Code Playgroud)

结果:

12,552,893 ticks
Run Code Online (Sandbox Code Playgroud)

使用对数

int firstDigit = (int)(Value / Math.Pow(10, (int)Math.Floor(Math.Log10(Value))));
Run Code Online (Sandbox Code Playgroud)

结果:

9,165,089 ticks
Run Code Online (Sandbox Code Playgroud)

循环

while (number >= 10)
    number /= 10;
Run Code Online (Sandbox Code Playgroud)

结果:

6,001,570 ticks
Run Code Online (Sandbox Code Playgroud)

条件语句

int firstdigit;
if (Value < 10)
     firstdigit = Value;
else if (Value < 100)
     firstdigit = Value / 10;
else if (Value < 1000)
     firstdigit = Value / 100;
else if (Value < 10000)
     firstdigit = Value / 1000;
else if (Value < 100000)
     firstdigit = Value / 10000;
else if (Value < 1000000)
     firstdigit = Value / 100000;
else if (Value < 10000000)
     firstdigit = Value / 1000000;
else if (Value < 100000000)
     firstdigit = Value / 10000000;
else if (Value < 1000000000)
     firstdigit = Value / 100000000;
else
     firstdigit = Value / 1000000000;
Run Code Online (Sandbox Code Playgroud)

结果:

1,421,659 ticks
Run Code Online (Sandbox Code Playgroud)

展开和优化循环

if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;
Run Code Online (Sandbox Code Playgroud)

结果:

1,399,788 ticks
Run Code Online (Sandbox Code Playgroud)

注意:

每个测试都要求Random.Next()下一个int

  • 这太琐碎了.我很欣赏你所做的一切,而且信息非常丰富,但对于99%的应用程序来说,这样做太过分了.我担心一些新手程序员可能会给人留下不好的印象.(硬核,过早优化可读性)但它仍然很有趣.:) (15认同)
  • +1 - 很棒的东西.这是一种镀金,豪华型的矫枉过正,这让你很喜欢编码.很多赞美你.不,斯图尔特,我认为这不会污染毫无戒心的新手.希望它能教会他们培养对软件的热爱. (13认同)
  • 查找表在哪里? (7认同)
  • +1基准测试,但我同意这是完全矫枉过正.如果你担心性能,那么你可能不应该首先使用C#:) (2认同)
  • @Vikash - 将 `char` 转换为 `int` 的计算结果为字符的代码点,因此将字符 `0` 转换为 48。减去 48 可以有效地转换为整数。再举一个例子,将字符“5”转换为“int”的结果是 53,然后减去 48 的结果是 5。 (2认同)

Ant*_*lev 124

这是如何做

int i = Math.Abs(386792);
while(i >= 10)
    i /= 10;
Run Code Online (Sandbox Code Playgroud)

并且i将包含你所需要的


Jar*_*Par 31

试试这个

public int GetFirstDigit(int number) {
  if ( number < 10 ) {
    return number;
  }
  return GetFirstDigit ( (number - (number % 10)) / 10);
}
Run Code Online (Sandbox Code Playgroud)

编辑

有几个人要求循环版本

public static int GetFirstDigitLoop(int number)
{
    while (number >= 10)
    {
        number = (number - (number % 10)) / 10;
    }
    return number;
}
Run Code Online (Sandbox Code Playgroud)


Len*_*ert 26

我能想到的最好的是:

int numberOfDigits = Convert.ToInt32(Math.Floor( Math.Log10( value ) ) );

int firstDigit = value / Math.Pow( 10, numberOfDigits );
Run Code Online (Sandbox Code Playgroud)

...

不是很漂亮:)

[编辑:第一个答案非常糟糕:)]

[编辑2:我可能会建议字符串操作解决方案,但]

[编辑3:码格式好:)]


Mik*_*vey 18

安东回答的变化:

 // cut down the number of divisions (assuming i is positive & 32 bits)
if (i >= 100000000) i /= 100000000;
if (i >= 10000) i /= 10000;
if (i >= 100) i /= 100;
if (i >= 10) i /= 10;
Run Code Online (Sandbox Code Playgroud)

  • 如果你把第一个"if"变为"while",那么它也适用于64位(但甚至是"丑陋的").+1 (3认同)

jga*_*fin 5

int myNumber = 8383;
char firstDigit = myNumber.ToString()[0];
// char = '8'
Run Code Online (Sandbox Code Playgroud)


aqu*_*nas 5

与Lennaert有同样的想法

int start = number == 0 ? 0 : number / (int) Math.Pow(10,Math.Floor(Math.Log10(Math.Abs(number))));
Run Code Online (Sandbox Code Playgroud)

这也适用于负数.