Как вы можете получить первую цифру в int (C #)? - PullRequest
74 голосов
/ 31 марта 2009

В C #, как лучше всего получить 1-ю цифру в int? Метод, который я придумал, состоит в том, чтобы превратить int в строку, найти 1-й символ строки, а затем превратить его обратно в int.

int start = Convert.ToInt32(curr.ToString().Substring(0, 1));

В то время как это делает работу, кажется, что есть, вероятно, хорошее, простое, математическое решение такой проблемы. Манипулирование струнами кажется неуклюжим.

Редактировать: независимо от разницы в скорости, mystring [0] вместо Substring () по-прежнему является просто манипулированием строкой

Ответы [ 25 ]

3 голосов
/ 31 марта 2009
int myNumber = 8383;
char firstDigit = myNumber.ToString()[0];
// char = '8'
3 голосов
/ 31 марта 2009

Очевидный, но медленный математический подход:

int firstDigit = (int)(i / Math.Pow(10, (int)Math.Log10(i))));
1 голос
/ 31 марта 2009

Очень просто (и, вероятно, довольно быстро, потому что это только сравнение и одно деление):

if(i<10)
   firstdigit = i;
else if (i<100)
   firstdigit = i/10;
else if (i<1000)
   firstdigit = i/100;
else if (i<10000)
   firstdigit = i/1000;
else if (i<100000)
   firstdigit = i/10000;
else (etc... all the way up to 1000000000)
1 голос
/ 23 июня 2014

Используя все приведенные ниже примеры, вы получите этот код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace Benfords
{
    class Program
    {
        static int FirstDigit1(int value)
        {
            return Convert.ToInt32(value.ToString().Substring(0, 1));
        }

        static int FirstDigit2(int value)
        {
            while (value >= 10) value /= 10;
            return value;
        }


        static int FirstDigit3(int value)
        {
            return (int)(value.ToString()[0]) - 48;
        }

        static int FirstDigit4(int value)
        {
            return (int)(value / Math.Pow(10, (int)Math.Floor(Math.Log10(value))));
        }

        static int FirstDigit5(int value)
        {
            if (value < 10) return value;
            if (value < 100) return value / 10;
            if (value < 1000) return value / 100;
            if (value < 10000) return value / 1000;
            if (value < 100000) return value / 10000;
            if (value < 1000000) return value / 100000;
            if (value < 10000000) return value / 1000000;
            if (value < 100000000) return value / 10000000;
            if (value < 1000000000) return value / 100000000;
            return value / 1000000000;
        }

        static int FirstDigit6(int value)
        {
            if (value >= 100000000) value /= 100000000;
            if (value >= 10000) value /= 10000;
            if (value >= 100) value /= 100;
            if (value >= 10) value /= 10;
            return value;
        }

        const int mcTests = 1000000;

        static void Main(string[] args)
        {
            Stopwatch lswWatch = new Stopwatch();
            Random lrRandom = new Random();

            int liCounter;

            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit1(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 1, lswWatch.ElapsedTicks);

            lswWatch.Reset();
            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit2(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 2, lswWatch.ElapsedTicks);

            lswWatch.Reset();
            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit3(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 3, lswWatch.ElapsedTicks);

            lswWatch.Reset();
            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit4(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 4, lswWatch.ElapsedTicks);

            lswWatch.Reset();
            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit5(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 5, lswWatch.ElapsedTicks);

            lswWatch.Reset();
            lswWatch.Start();
            for (liCounter = 0; liCounter < mcTests; liCounter++)
                FirstDigit6(lrRandom.Next());
            lswWatch.Stop();
            Console.WriteLine("Test {0} = {1} ticks", 6, lswWatch.ElapsedTicks);

            Console.ReadLine();
        }
    }
}

Я получаю следующие результаты на двухъядерном процессоре AMD Ahtlon 64 X2 4200+ (2,2 ГГц):

Test 1 = 2352048 ticks
Test 2 = 614550 ticks
Test 3 = 1354784 ticks
Test 4 = 844519 ticks
Test 5 = 150021 ticks
Test 6 = 192303 ticks

Но получите это на AMD FX 8350 Eight Core (4,00 ГГц)

Test 1 = 3917354 ticks
Test 2 = 811727 ticks
Test 3 = 2187388 ticks
Test 4 = 1790292 ticks
Test 5 = 241150 ticks
Test 6 = 227738 ticks

Так что, будет ли метод 5 или 6 быстрее, зависит от ЦП, я могу только предположить, что это связано с тем, что предсказание ветвления в командном процессоре ЦП более разумно для нового процессора, но я не совсем уверен.

У меня нет каких-либо процессоров Intel, может, кто-нибудь может проверить это для нас?

1 голос
/ 22 апреля 2009

Провел несколько тестов с одним из моих коллег здесь и обнаружил, что большинство решений не работают для чисел ниже 0.

  public int GetFirstDigit(int number)
    {
        number = Math.Abs(number); <- makes sure you really get the digit!

        if (number < 10)
        {
            return number;
        }
        return GetFirstDigit((number - (number % 10)) / 10);
    }
0 голосов
/ 17 апреля 2019

Проверьте это тоже:

int get1digit(Int64 myVal)
{
    string q12 = myVal.ToString()[0].ToString();
    int i = int.Parse(q12);
    return i;
}

Также хорошо, если вы хотите несколько номеров:

int get3digit(Int64 myVal) //Int64 or whatever numerical data you have
{
    char mg1 = myVal.ToString()[0];
    char mg2 = myVal.ToString()[1];
    char mg3 = myVal.ToString()[2];
    char[] chars = { mg1, mg2, mg3 };
    string q12= new string(chars);
    int i = int.Parse(q12);
    return i;
}
0 голосов
/ 12 июля 2015

Это то, что я обычно делаю, пожалуйста, обратитесь к моей функции ниже:

Эта функция может извлекать вхождение первой цифры из любой строки, которую вы можете изменить, и использовать эту функцию в соответствии с вашим использованием

   public static int GetFirstNumber(this string strInsput)
    {
        int number = 0;
        string strNumber = "";
        bool bIsContNo = true;
        bool bNoOccued = false;

        try
        {
            var arry = strInsput.ToCharArray(0, strInsput.Length - 1);

            foreach (char item in arry)
            {
                if (char.IsNumber(item))
                {
                    strNumber = strNumber + item.ToString();

                    bIsContNo = true;

                    bNoOccued = true;
                }
                else
                {
                    bIsContNo = false;
                }

                if (bNoOccued && !bIsContNo)
                {
                    break;
                }


            }

            number = Convert.ToInt32(strNumber);

        }
        catch (Exception ex)
        {

            return 0;
        }

        return number;

    }
0 голосов
/ 31 марта 2009

Просто чтобы дать вам альтернативу, вы можете многократно делить целое число на 10, а затем откатить одно значение, как только вы достигнете нуля. Поскольку строковые операции обычно медленны, это может быть быстрее, чем манипулирование строками, но отнюдь не элегантно.

Примерно так:

while(curr>=10)
     curr /= 10;
0 голосов
/ 01 июля 2010
int i = 4567789;
int digit1 = int.Parse(i.ToString()[0].ToString());
0 голосов
/ 24 апреля 2010

Очень простой способ получить последнюю цифру:

int myInt = 1821;

int lastDigit = myInt - ((myInt/10)*10); // 1821 - 1820 = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...