Manier om het aantal cijfers in een int te krijgen?

Is er een nettere manier om het aantal cijfers in een int te krijgen dan deze methode?

int numDigits = String.valueOf(1000).length();

Antwoord 1, autoriteit 100%

Uw String-gebaseerde oplossing is perfect in orde, er is niets “onnetjes” aan. Je moet je realiseren dat wiskundig gezien getallen geen lengte hebben en ook geen cijfers. Lengte en cijfers zijn beide eigenschappen van een fysieke representatievan een getal in een specifieke basis, d.w.z. een String.

Een op logaritme gebaseerde oplossing doet (sommige van) dezelfde dingen die de op String gebaseerde oplossing intern doet, en waarschijnlijk (onbeduidend) sneller omdat het alleen de lengte produceert en de cijfers negeert. Maar ik zou het eigenlijk niet duidelijker van opzet vinden – en dat is de belangrijkste factor.


Antwoord 2, autoriteit 76%

De logaritme is je vriend:

int n = 1000;
int length = (int)(Math.log10(n)+1);

NB: alleen geldig voor n > 0.


Antwoord 3, autoriteit 45%

De snelste aanpak: verdeel en heers.

Ervan uitgaande dat uw bereik 0 tot MAX_INT is, heeft u 1 tot 10 cijfers. U kunt dit interval benaderen met verdeel en heers, met maximaal 4 vergelijkingen per invoer. Eerst verdeel je [1..10] in [1..5] en [6..10] met één vergelijking, en vervolgens verdeel je elk lengte 5-interval met één vergelijking in één lengte 3 en één lengte 2-interval. Het lengte 2-interval vereist nog één vergelijking (totaal 3 vergelijkingen), het lengte 3-interval kan worden onderverdeeld in lengte 1-interval (oplossing) en een lengte 2-interval. Je hebt dus 3 of 4 vergelijkingen nodig.

Geen divisies, geen drijvende puntenactiviteiten, geen dure logaritmen, alleen integer-vergelijkingen.

code (lang maar snel):

if (n < 100000) {
    // 5 or less
    if (n < 100){
        // 1 or 2
        if (n < 10)
            return 1;
        else
            return 2;
    } else {
        // 3 or 4 or 5
        if (n < 1000)
            return 3;
        else {
            // 4 or 5
            if (n < 10000)
                return 4;
            else
                return 5;
        }
    }
} else {
    // 6 or more
    if (n < 10000000) {
        // 6 or 7
        if (n < 1000000)
            return 6;
        else
            return 7;
    } else {
        // 8 to 10
        if (n < 100000000)
            return 8;
        else {
            // 9 or 10
            if (n < 1000000000)
                return 9;
            else
                return 10;
        }
    }
}

Benchmark (na JVM Warm-Up) – zie hieronder code om te zien hoe de benchmark wordt uitgevoerd:

  1. Baseline-methode (met string.length):
    2145MS
  2. Log10-methode: 711ms = 3.02 keer
    zo snel als basislijn
  3. herhaaldelijk deel: 2797ms = 0.77 keer
    zo snel als basislijn
  4. Divide-and-Conquer: 74ms = 28.99
    keer zo snel als basislijn

Volledige code:

public static void main(String[] args) throws Exception {
    // validate methods:
    for (int i = 0; i < 1000; i++)
        if (method1(i) != method2(i))
            System.out.println(i);
    for (int i = 0; i < 1000; i++)
        if (method1(i) != method3(i))
            System.out.println(i + " " + method1(i) + " " + method3(i));
    for (int i = 333; i < 2000000000; i += 1000)
        if (method1(i) != method3(i))
            System.out.println(i + " " + method1(i) + " " + method3(i));
    for (int i = 0; i < 1000; i++)
        if (method1(i) != method4(i))
            System.out.println(i + " " + method1(i) + " " + method4(i));
    for (int i = 333; i < 2000000000; i += 1000)
        if (method1(i) != method4(i))
            System.out.println(i + " " + method1(i) + " " + method4(i));
    // work-up the JVM - make sure everything will be run in hot-spot mode
    allMethod1();
    allMethod2();
    allMethod3();
    allMethod4();
    // run benchmark
    Chronometer c;
    c = new Chronometer(true);
    allMethod1();
    c.stop();
    long baseline = c.getValue();
    System.out.println(c);
    c = new Chronometer(true);
    allMethod2();
    c.stop();
    System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
    c = new Chronometer(true);
    allMethod3();
    c.stop();
    System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
    c = new Chronometer(true);
    allMethod4();
    c.stop();
    System.out.println(c + " = " + StringTools.formatDouble((double)baseline / c.getValue() , "0.00") + " times as fast as baseline");
}
private static int method1(int n) {
    return Integer.toString(n).length();
}
private static int method2(int n) {
    if (n == 0)
        return 1;
    return (int)(Math.log10(n) + 1);
}
private static int method3(int n) {
    if (n == 0)
        return 1;
    int l;
    for (l = 0 ; n > 0 ;++l)
        n /= 10;
    return l;
}
private static int method4(int n) {
    if (n < 100000) {
        // 5 or less
        if (n < 100) {
            // 1 or 2
            if (n < 10)
                return 1;
            else
                return 2;
        } else {
            // 3 or 4 or 5
            if (n < 1000)
                return 3;
            else {
                // 4 or 5
                if (n < 10000)
                    return 4;
                else
                    return 5;
            }
        }
    } else {
        // 6 or more
        if (n < 10000000) {
            // 6 or 7
            if (n < 1000000)
                return 6;
            else
                return 7;
        } else {
            // 8 to 10
            if (n < 100000000)
                return 8;
            else {
                // 9 or 10
                if (n < 1000000000)
                    return 9;
                else
                    return 10;
            }
        }
    }
}
private static int allMethod1() {
    int x = 0;
    for (int i = 0; i < 1000; i++)
        x = method1(i);
    for (int i = 1000; i < 100000; i += 10)
        x = method1(i);
    for (int i = 100000; i < 1000000; i += 100)
        x = method1(i);
    for (int i = 1000000; i < 2000000000; i += 200)
        x = method1(i);
    return x;
}
private static int allMethod2() {
    int x = 0;
    for (int i = 0; i < 1000; i++)
        x = method2(i);
    for (int i = 1000; i < 100000; i += 10)
        x = method2(i);
    for (int i = 100000; i < 1000000; i += 100)
        x = method2(i);
    for (int i = 1000000; i < 2000000000; i += 200)
        x = method2(i);
    return x;
}
private static int allMethod3() {
    int x = 0;
    for (int i = 0; i < 1000; i++)
        x = method3(i);
    for (int i = 1000; i < 100000; i += 10)
        x = method3(i);
    for (int i = 100000; i < 1000000; i += 100)
        x = method3(i);
    for (int i = 1000000; i < 2000000000; i += 200)
        x = method3(i);
    return x;
}
private static int allMethod4() {
    int x = 0;
    for (int i = 0; i < 1000; i++)
        x = method4(i);
    for (int i = 1000; i < 100000; i += 10)
        x = method4(i);
    for (int i = 100000; i < 1000000; i += 100)
        x = method4(i);
    for (int i = 1000000; i < 2000000000; i += 200)
        x = method4(i);
    return x;
}

Nogmaals, benchmark:

  1. basislijnmethode (met String.length): 2145ms
  2. log10-methode: 711 ms = 3,02 keer zo snel als baseline
  3. herhaalde deling: 2797 ms = 0,77 keer zo snel als baseline
  4. verdeel en heers: 74 ms = 28,99 keer zo snel als basislijn

Bewerken

Nadat ik de benchmark had geschreven, nam ik een voorproefje van Integer.toString vanaf Java 6, en ik ontdekte dat het gebruik maakt van:

final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                  99999999, 999999999, Integer.MAX_VALUE };
// Requires positive x
static int stringSize(int x) {
    for (int i=0; ; i++)
        if (x <= sizeTable[i])
            return i+1;
}

Ik heb het vergeleken met mijn verdeel-en-heers-oplossing:

  1. verdeel en heers: 104ms
  2. Java 6-oplossing – herhaal en vergelijk: 406ms

De mijne is ongeveer 4x zo snel als de Java 6-oplossing.


Antwoord 4, autoriteit 3%

Twee opmerkingen over uw benchmark: Java is een complexe omgeving, met just-in-time compileren en garbagecollection enzovoort, dus om een eerlijke vergelijking te krijgen, als ik een benchmark uitvoer, voeg ik altijd: (a) toe de twee tests in een lus die ze 5 of 10 keer achter elkaar uitvoert. Heel vaak is de looptijd bij de tweede doorgang door de lus heel anders dan bij de eerste. En (b) Na elke “benadering”, doe ik een System.gc() om te proberen een garbagecollection te activeren. Anders kan de eerste benadering een heleboel objecten genereren, maar niet voldoende om een garbagecollection te forceren, dan creëert de tweede benadering een paar objecten, is de heap uitgeput en wordt de garbagecollection uitgevoerd. Dan wordt de tweede benadering “in rekening gebracht” voor het opruimen van het afval dat door de eerste benadering is achtergelaten. Heel oneerlijk!

Dat gezegd hebbende, maakte geen van beide een significant verschil in dit voorbeeld.

Met of zonder die aanpassingen kreeg ik heel andere resultaten dan jij. Toen ik dit uitvoerde, ja, de toString-benadering gaf looptijden van 6400 tot 6600 millis, terwijl de logbenadering 20.000 tot 20.400 millis bedroeg. In plaats van iets sneller te zijn, was de logbenadering voor mij 3 keer langzamer.

Merk op dat de twee benaderingen zeer verschillende kosten met zich meebrengen, dus dit is niet helemaal schokkend: de toString-benadering zal veel tijdelijke objecten creëren die moeten worden opgeschoond, terwijl de logbenadering intensievere berekeningen vereist. Dus misschien is het verschil dat op een machine met minder geheugen, toString meer afvalinzamelingsrondes nodig heeft, terwijl op een machine met een langzamere processor de extra berekening van het logboek pijnlijker zou zijn.

Ik heb ook een derde benadering geprobeerd. Ik heb deze kleine functie geschreven:

static int numlength(int n)
{
    if (n == 0) return 1;
    int l;
    n=Math.abs(n);
    for (l=0;n>0;++l)
        n/=10;
    return l;           
}

Die liep in 1600 tot 1900 millis – minder dan 1/3 van de ToString-aanpak, en 1/10 de log-aanpak op mijn machine.

Als u een breed scala aan cijfers had, kunt u het verder versnellen door te beginnen met het delen van 1.000 of 1.000.000 om het aantal keren door de lus te verkleinen. Ik heb daar niet mee gespeeld.


5, Autoriteit 3%

kan nog geen reactie achterlaten, dus ik zal als een afzonderlijk antwoord posten.

De op logaritme gebaseerde oplossing berekent niet het juiste aantal cijfers voor zeer grote lange gehele getallen, bijvoorbeeld:

long n = 99999999999999999L;
// correct answer: 17
int numberOfDigits = String.valueOf(n).length();
// incorrect answer: 18
int wrongNumberOfDigits = (int) (Math.log10(n) + 1); 

LogaritM-gebaseerd Oplossing berekent een verkeerd aantal cijfers in grote gehele getallen


6, Autoriteit 2%

Aangezien het aantal cijfers in basis 10 van een geheel getal slechts 1 + afkappen (log10 (nummer)) , kunt u doen:

public class Test {
    public static void main(String[] args) {
        final int number = 1234;
        final int digits = 1 + (int)Math.floor(Math.log10(number));
        System.out.println(digits);
    }
}

bewerkt omdat mijn laatste bewerking het COD-voorbeeld heeft vastgesteld, maar niet de beschrijving.


7

De oplossing van Marian aangepast voor Lange Type nummers (tot 9.223.372.036.854.775.807), voor het geval iemand wil kopiëren & amp; plak het.
In het programma schreef ik dit voor getallen tot 10000 veel waarschijnlijker, dus ik heb een specifieke tak voor hen gemaakt. Hoe dan ook, het zal geen significant verschil maken.

public static int numberOfDigits (long n) {     
    // Guessing 4 digit numbers will be more probable.
    // They are set in the first branch.
    if (n < 10000L) { // from 1 to 4
        if (n < 100L) { // 1 or 2
            if (n < 10L) {
                return 1;
            } else {
                return 2;
            }
        } else { // 3 or 4
            if (n < 1000L) {
                return 3;
            } else {
                return 4;
            }
        }           
    } else  { // from 5 a 20 (albeit longs can't have more than 18 or 19)
        if (n < 1000000000000L) { // from 5 to 12
            if (n < 100000000L) { // from 5 to 8
                if (n < 1000000L) { // 5 or 6
                    if (n < 100000L) {
                        return 5;
                    } else {
                        return 6;
                    }
                } else { // 7 u 8
                    if (n < 10000000L) {
                        return 7;
                    } else {
                        return 8;
                    }
                }
            } else { // from 9 to 12
                if (n < 10000000000L) { // 9 or 10
                    if (n < 1000000000L) {
                        return 9;
                    } else {
                        return 10;
                    }
                } else { // 11 or 12
                    if (n < 100000000000L) {
                        return 11;
                    } else {
                        return 12;
                    }
                }
            }
        } else { // from 13 to ... (18 or 20)
            if (n < 10000000000000000L) { // from 13 to 16
                if (n < 100000000000000L) { // 13 or 14
                    if (n < 10000000000000L) { 
                        return 13;
                    } else {
                        return 14;
                    }
                } else { // 15 or 16
                    if (n < 1000000000000000L) {
                        return 15;
                    } else {
                        return 16;
                    }
                }
            } else { // from 17 to ...¿20?
                if (n < 1000000000000000000L) { // 17 or 18
                    if (n < 100000000000000000L) {
                        return 17;
                    } else {
                        return 18;
                    }
                } else { // 19? Can it be?
                    // 10000000000000000000L is'nt a valid long.
                    return 19;
                }
            }
        }
    }
}

8

een andere stringbenadering. Kort en zoet – voor een geheel getal n.

int length = ("" + n).length();

9

Kan ik het proberen? 😉

Gebaseerd op de oplossing van Dirk

final int digits = number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));

Antwoord 10

Wat dacht je van gewone oude wiskunde? Deel door 10 totdat je 0 bereikt.

public static int getSize(long number) {
        int count = 0;
        while (number > 0) {
            count += 1;
            number = (number / 10);
        }
        return count;
    }

Antwoord 11

Marian’s oplossing, nu met Ternary:

public int len(int n){
        return (n<100000)?((n<100)?((n<10)?1:2):(n<1000)?3:((n<10000)?4:5)):((n<10000000)?((n<1000000)?6:7):((n<100000000)?8:((n<1000000000)?9:10)));
    }

Omdatwe het kunnen.


Antwoord 12

Nieuwsgierig, ik heb geprobeerd het te benchmarken …

import org.junit.Test;
import static org.junit.Assert.*;
public class TestStack1306727 {
    @Test
    public void bench(){
        int number=1000;
        int a= String.valueOf(number).length();
        int b= 1 + (int)Math.floor(Math.log10(number));
        assertEquals(a,b);
        int i=0;
        int s=0;
        long startTime = System.currentTimeMillis();
        for(i=0, s=0; i< 100000000; i++){
            a= String.valueOf(number).length();
            s+=a;
        }
        long stopTime = System.currentTimeMillis();
        long runTime = stopTime - startTime;
        System.out.println("Run time 1: " + runTime);
        System.out.println("s: "+s);
        startTime = System.currentTimeMillis();
        for(i=0,s=0; i< 100000000; i++){
            b= number==0?1:(1 + (int)Math.floor(Math.log10(Math.abs(number))));
            s+=b;
        }
        stopTime = System.currentTimeMillis();
        runTime = stopTime - startTime;
        System.out.println("Run time 2: " + runTime);
        System.out.println("s: "+s);
        assertEquals(a,b);
    }
}

de resultaten zijn:

Duurtijd 1: 6765
s: 400000000
Looptijd 2: 6000
s: 400000000

Nu vraag ik me af of mijn benchmark echt iets betekent, maar ik krijg wel consistente resultaten (variaties binnen een ms) over meerdere runs van de benchmark zelf … 🙂 Het lijkt erop dat het nutteloos is om dit te proberen en te optimaliseren. ..


edit: na de opmerking van ptomli heb ik ‘nummer’ vervangen door ‘i’ in de bovenstaande code en kreeg de volgende resultaten over 5 runs van de bank:

Duurtijd 1: 11500
s: 788888890
Looptijd 2: 8547
s: 788888890
Looptijd 1: 11485
s: 788888890
Looptijd 2: 8547
s: 788888890
Looptijd 1: 11469
s: 788888890
Looptijd 2: 8547
s: 788888890
Looptijd 1: 11500
s: 788888890
Looptijd 2: 8547
s: 788888890
Looptijd 1: 11484
s: 788888890
Looptijd 2: 8547
s: 788888890

Antwoord 13

Met ontwerp (gebaseerd op probleem). Dit is een alternatief voor verdeel en heers. We zullen eerst een enum definiëren (aangezien het alleen voor een niet-ondertekende int is).

public enum IntegerLength {
    One((byte)1,10),
    Two((byte)2,100),
    Three((byte)3,1000),
    Four((byte)4,10000),
    Five((byte)5,100000),
    Six((byte)6,1000000),
    Seven((byte)7,10000000),
    Eight((byte)8,100000000),
    Nine((byte)9,1000000000);
    byte length;
    int value;
    IntegerLength(byte len,int value) {
        this.length = len;
        this.value = value;
    }
    public byte getLenght() {
        return length;
    }
    public int getValue() {
        return value;
    }
}

Nu gaan we een klasse definiëren die door de waarden van de enum gaat en de juiste lengte vergelijken en retourneren.

public class IntegerLenght {
    public static byte calculateIntLenght(int num) {    
        for(IntegerLength v : IntegerLength.values()) {
            if(num < v.getValue()){
                return v.getLenght();
            }
        }
        return 0;
    }
}

De looptijd van deze oplossing is hetzelfde als de verdeel-en-heers-aanpak.


Antwoord 14

geen String API, geen utils, geen typeconversie, alleen pure java-iteratie ->

public static int getNumberOfDigits(int input) {
    int numOfDigits = 1;
    int base = 1;
    while (input >= base * 10) {
        base = base * 10;
        numOfDigits++;
    }
    return numOfDigits;
 }

Je kunt long gaan voor grotere waarden als je wilt.


Antwoord 15

Hoe zit het met deze recursieve methode?

   private static int length = 0;
    public static int length(int n) {
    length++;
    if((n / 10) < 10) {
        length++;
    } else {
        length(n / 10);
    }
    return length;
}

Antwoord 16

eenvoudige oplossing:

public class long_length {
    long x,l=1,n;
    for (n=10;n<x;n*=10){
        if (x/n!=0){
            l++;
        }
    }
    System.out.print(l);
}

Antwoord 17

Een heel eenvoudige oplossing:

public int numLength(int n) {
  for (int length = 1; n % Math.pow(10, length) != n; length++) {}
  return length;
}

Antwoord 18

Of in plaats daarvan kun je de lengte controleren als het getal groter of kleiner is dan het gewenste getal.

   public void createCard(int cardNumber, int cardStatus, int customerId) throws SQLException {
    if(cardDao.checkIfCardExists(cardNumber) == false) {
        if(cardDao.createCard(cardNumber, cardStatus, customerId) == true) {
            System.out.println("Card created successfully");
        } else {
        }
    } else {
        System.out.println("Card already exists, try with another Card Number");
        do {
            System.out.println("Enter your new Card Number: ");
            scan = new Scanner(System.in);
            int inputCardNumber = scan.nextInt();
            cardNumber = inputCardNumber;
        } while(cardNumber < 95000000);
        cardDao.createCard(cardNumber, cardStatus, customerId);
    }
}

}


Antwoord 19

Ik heb nog geen oplossing op basis van vermenigvuldiging gezien. Logaritme-, divisie- en stringgebaseerde oplossingen zullen nogal onpraktisch worden tegen miljoenen testgevallen, dus hier is er een voor ints:

/**
 * Returns the number of digits needed to represents an {@code int} value in 
 * the given radix, disregarding any sign.
 */
public static int len(int n, int radix) {
    radixCheck(radix); 
    // if you want to establish some limitation other than radix > 2
    n = Math.abs(n);
    int len = 1;
    long min = radix - 1;
    while (n > min) {
        n -= min;
        min *= radix;
        len++;
    }
    return len;
}

In basis 10 werkt dit omdat n in wezen wordt vergeleken met 9, 99, 999… aangezien min 9, 90, 900… is en n wordt afgetrokken met 9, 90, 900…

Helaas is dit niet overdraagbaar naar longdoor simpelweg elke instantie van intte vervangen vanwege overloop. Aan de andere kant, het is gewoon zo dat het zalwerken voor bases 2 en 10 (maar faalt ernstig voor de meeste andere bases). Je hebt een opzoektabel nodig voor de overlooppunten (of een delingstest… ieuw)

/**
 * For radices 2 &le r &le Character.MAX_VALUE (36)
 */
private static long[] overflowpt = { -1, -1, 4611686018427387904L,
    8105110306037952534L, 3458764513820540928L, 5960464477539062500L,
    3948651115268014080L, 3351275184499704042L, 8070450532247928832L,
    1200757082375992968L, 9000000000000000000L, 5054470284992937710L,
    2033726847845400576L, 7984999310198158092L, 2022385242251558912L,
    6130514465332031250L, 1080863910568919040L, 2694045224950414864L,
    6371827248895377408L, 756953702320627062L, 1556480000000000000L,
    3089447554782389220L, 5939011215544737792L, 482121737504447062L,
    839967991029301248L, 1430511474609375000L, 2385723916542054400L,
    3902460517721977146L, 6269893157408735232L, 341614273439763212L,
    513726300000000000L, 762254306892144930L, 1116892707587883008L,
    1617347408439258144L, 2316231840055068672L, 3282671350683593750L,
    4606759634479349760L};
public static int len(long n, int radix) {
    radixCheck(radix);
    n = abs(n);
    int len = 1;
    long min = radix - 1;
    while (n > min) {
        len++;
        if (min == overflowpt[radix]) break;
        n -= min;
        min *= radix;
    }
    return len;
}

Antwoord 20

Men wil dit vooral doen omdat hij/zij het wil “presenteren”, wat meestal betekent dat het uiteindelijk expliciet of impliciet moet worden “toString-ed” (of op een andere manier getransformeerd) hoe dan ook; voordat het kan worden gepresenteerd (bijvoorbeeld afgedrukt).

Als dat het geval is, probeer dan de noodzakelijke “toString” expliciet te maken en tel de bits.


Antwoord 21

We kunnen dit bereiken met een recursieve lus

   public static int digitCount(int numberInput, int i) {
        while (numberInput > 0) {
        i++;
        numberInput = numberInput / 10;
        digitCount(numberInput, i);
        }
        return i;
    }
    public static void printString() {
        int numberInput = 1234567;
        int digitCount = digitCount(numberInput, 0);
        System.out.println("Count of digit in ["+numberInput+"] is ["+digitCount+"]");
    }

Antwoord 22

Ik heb deze functie geschreven nadat ik de broncode van Integer.javahad bekeken.

private static int stringSize(int x) {
    final int[] sizeTable = {9, 99, 999, 9_999, 99_999, 999_999, 9_999_999,
            99_999_999, 999_999_999, Integer.MAX_VALUE};
    for (int i = 0; ; ++i) {
        if (x <= sizeTable[i]) {
            return i + 1;
        }
    }
}

Antwoord 23

Ik zie mensen String-bibliotheken gebruiken of zelfs de Integer-klasse. Daar is niets mis mee, maar het algoritme om het aantal cijfers te krijgen is niet zo ingewikkeld. Ik gebruik een long in dit voorbeeld, maar het werkt net zo goed met een int.

private static int getLength(long num) {
    int count = 1;
    while (num >= 10) {
        num = num / 10;
        count++;
    }
    return count;
}

Antwoord 24

Een van de efficiënte manieren om het aantal cijfers in een int-variabele te tellen, is door een methode digitsCounterte definiëren met een vereist aantal voorwaardelijke instructies.
De aanpak is eenvoudig, we zullen controleren voor elk bereik waarin een ncijfer kan liggen:
0: 9zijn Singlecijfers
10 : 99zijn Doublecijfers
100 : 999zijn Triplecijfers enzovoort…

   static int digitsCounter(int N)
    {   // N = Math.abs(N); // if `N` is -ve
        if (0 <= N && N <= 9) return 1;
        if (10 <= N && N <= 99) return 2;
        if (100 <= N && N <= 999) return 3;
        if (1000 <= N && N <= 9999) return 4;
        if (10000 <= N && N <= 99999) return 5;
        if (100000 <= N && N <= 999999) return 6;
        if (1000000 <= N && N <= 9999999) return 7;
        if (10000000 <= N && N <= 99999999) return 8;
        if (100000000 <= N && N <= 999999999) return 9;
        return 10;
    }

Een schonere manier om dit te doen, is door het vinkje voor de onderlimieten te verwijderen, aangezien dit niet nodig is als we op een sequentiële manier te werk gaan.

   static int digitsCounter(int N)
    {
        N = N < 0 ? -N : N;
        if (N <= 9) return 1;
        if (N <= 99) return 2;
        if (N <= 999) return 3;
        if (N <= 9999) return 4;
        if (N <= 99999) return 5;
        if (N <= 999999) return 6;
        if (N <= 9999999) return 7;
        if (N <= 99999999) return 8;
        if (N <= 999999999) return 9;
        return 10; // Max possible digits in an 'int'
    }

25

Hier is een heel eenvoudige methode die ik heb gemaakt voor elk nummer:

public static int numberLength(int userNumber) {
    int numberCounter = 10;
    boolean condition = true;
    int digitLength = 1;
    while (condition) {
        int numberRatio = userNumber / numberCounter;
        if (numberRatio < 1) {
            condition = false;
        } else {
            digitLength++;
            numberCounter *= 10;
        }
    }
    return digitLength; 
}

De manier waarop het werkt, is met de cijfertellervariabele is dat 10 = 1-cijferige ruimte. Bijvoorbeeld .1 = 1 tiende = & GT; 1 cijfer ruimte. Daarom als u int number = 103342;krijgt u 6, want dat is het equivalent van .000001-ruimtes terug. Ook heeft iemand een betere variabele naam voor numberCounter? Ik kan niets beters bedenken.

EDIT: heb gewoon gedacht aan een betere verklaring. In essentie wat deze terwijl Loop het doet is het maken, zodat je je nummer met 10 verdeling, totdat het minder dan één is. In essentie, wanneer je iets verdelen door 10, bewegen je het een nummerruimte terug, dus je deelt het eenvoudig met 10 tot je bereikt & lt; 1 voor het aantal cijfers in je nummer.

Hier is een andere versie die het aantal cijfers in een decimaal kan tellen:

public static int repeatingLength(double decimalNumber) {
    int numberCounter = 1;
    boolean condition = true;
    int digitLength = 1;
    while (condition) {
        double numberRatio = decimalNumber * numberCounter;
        if ((numberRatio - Math.round(numberRatio)) < 0.0000001) {
            condition = false;
        } else {
            digitLength++;
            numberCounter *= 10;
        }
    }
    return digitLength - 1;
}

Other episodes