2010-09-29 14 views

Odpowiedz

4

trochę trudne do obsługi liczb ujemnych i przypadek, gdy wejście jest zerowy:

int length(int n) 
{ 
    int len = 0; 
    if (n < 0) { len = 1; n = -n; } 
    while (n > 9) { 
     n /= 10; 
     len++; 
    } 
    return len+1; 
} 
+0

+1 za ostrożne i szybkie podejście. Specyfikacja miała liczyć cyfry, więc nie trzeba ustawiać osobno dla wartości ujemnych. Czy init len ​​na 1 i zwróć len. –

6

Nie ma takiej funkcji dostępnych w bibliotece C++. Można jednak użyć prostego trybu: std::stringstream.

Spróbuj tego (obsługuje także liczby ujemne).

int a =-12345,x; 
    x = std::abs(a) 
    std::stringstream s; 
    s << x; 
    std::cout<<s.str().size(); 
+1

Lokalizacja i faktoring są dobre: ​​'x = a <0? -a: a; ', ale porzuciłbym x i umieściłem to wyrażenie prosto w strumieniu. Bardzo C++, ale bardzo ciężki. –

2

Musisz podzielić go przez 10 (zakładając, że jest liczbą całkowitą). Robisz to, ponieważ usuwasz cyfrę za każdym razem, gdy pętla się iteruje.

coś wzdłuż linii:

int number; 
int digits; 
while (number > 0) 
{ 
    digits++; 
    number /= 10; 
} 

Prawdopodobnie będziesz chciał upewnić się, że liczba ta wynosi zero na początku.

2
int intlen(float num) { 
    int cnt = 0; 
    while(num >= 1) { 
     num = num/10; 
     cnt++; 
    } 
    return cnt; 
} 
+0

Numer 0 zawiera 0 cyfr? – dreamlax

+0

Liczby ujemne również nie zawierają cyfr? – dreamlax

10

Dla liczb dodatnich, użyj log10:

int a = 1234; 
int len = static_cast<int>(log10(a)+1.); 

Jeśli chcesz być dokładny:

int length(int a) 
{ 
    int b = abs(a); 
    if (b == 0) return 1; 
    return static_cast<int>(log10(b)+1.); 
} 

Z powiedział, że byłoby lepszym wyborem zrobić powtarzającego dzielenie przez 10 w praktyce.

int length(int a) 
{ 
    int b = 0; 
    for (a = abs(a); a != 0; b++, a /= 10) continue; 
    return b; 
} 
+1

Powoduje pytanie, czy Standard zezwala na implementację, gdzie powiedz 'log10 (10)' zwraca 0.9999999999 ...? Po prostu nie wiem (lub nie ufam implementacjom, aby spełnić wymagania, ponieważ będą robić to, co robi sprzęt), więc preferuję podejście int według cyfry po cyfrze, nawet jeśli jest to bardziej matematycznie eleganckie. Myśli? –

+0

Niedoszacowanie przez 1 - tj. dla twojego przykładu z 1234 zwraca 3. Również nie kompiluje się (przynajmniej w VC++), ponieważ wywołanie log10 jest niejednoznaczne - musisz jawnie rzucić int na podwójne pierwsze. Chyba miałeś zamiar przekazać b do log10 zamiast do? – Peter

+0

Jedziesz obok. log10 (5) to 0.6989700 ... kiedy odrzucisz to z powrotem do int, otrzymasz 0. 5 "z pewnością ma więcej niż zero cyfr. Ponadto, weź abs (a) i umieść go w b, ale potem idź dalej i weź log10 z (być może i nie pozytywnego) i tak – SingleNegationElimination

7

Prawdopodobnie znaczy, trzeba łańcuch zawierający numery zamiast int w python:

>>> i = 123456789 
>>> len(i) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
TypeError: object of type 'int' has no len() 
>>> len(str(i)) 
9 

Jeśli jest to również w przypadku C++ jest to łatwe do znalezienia długość łańcucha przy użyciu:

my_str_value.length() 

lub ciąg C z użyciem strlen

0

Oto littl Przykład E:

int numberDigits(int n) { 
    char buffer[100]; 
    itoa(n,buffer,10); 
    int len=0; 
    while (buffer[len]!=0) { len++; } 
    return len; 
} 
+0

Warto zamieścić jako alternatywę. Należy pominąć dowolny prowadzący "-". Pomimo uniknięcia strlen(), tylko atoi() na pewno będzie wolniejsze niż inne rozwiązania div-by-10 .... –

+0

Byłoby to problem, jeśli prędkość jest bardzo wrażliwa w jego aplikacji. –

5

Hmm ... Python:

>>> len(5) 

Traceback (most recent call last): 
    File "<pyshell#45>", line 1, in <module> 
    len(5) 
TypeError: object of type 'int' has no len() 

nie to, czego chciał?

cóż, załóżmy, że masz rzeczywistą liczbę całkowitą. baza logów 10 powie Ci, co chcesz wiedzieć numerycznie, czyli jeśli yournumber == pow(10, digits), to log10(yournumber) == digits! niestety, jeśli twoja liczba nie jest dokładną potęgą 10, będziesz miał część ułamkową, którą możesz zająć. Łatwo jest sobie z tym poradzić dzięki funkcji floor(), która po prostu się kończy. bądźcie ostrożni wobec liczb ujemnych, ponieważ logarytmy są niezdefiniowane w liczbach rzeczywistych dla wartości niepodatnych.

#include <iostream> 
#include <math.h> 

int main() 
{ 
    std::cout << floor(log10(5))+1 << std::endl; 
    std::cout << floor(log10(30))+1 << std::endl; 
    std::cout << floor(log10(2000))+1 << std::endl; 
    std::cout << floor(log10(16000))+1 << std::endl; 
} 

musimy dodać 1, ponieważ 10 do 1 jest nadal 10, więc jesteśmy wyłączeni o jeden. Dodaj jeden do wykładnika i masz cyfry!

+0

Doskonałe wyjaśnienie.+1 Jak sądzisz o możliwych problemach z precyzją z zmiennoprzecinkowym, które zostały poruszone w komentarzach do mojej odpowiedzi? – JoshD

+0

@JoshD: cóż, 'log10 (x)' jest niezdefiniowane dla nie-pozytywnego x, ale poza tym problemem będzie to zawsze poprawne. Zauważ, że 'log10 (10.0)' jest dokładnie 1.0. podłoga tego wynosi 1, 1 + 1 to dwa. – SingleNegationElimination

0

Pomijając na chwilę, że len() w Pythonie zwraca liczbę elementów w sekwencji, a nie liczbę cyfr w liczbie całkowitej, oto funkcja policzyć liczbę cyfr w liczbie całkowitej bez dzielenia (tak jak powinien być znacznie szybsze niż podobne rozwiązania wykorzystujące podział).

int number_of_digits(int value) 
{ 
    int count = 0; 
    int i = 1; 

    if (value < 0) 
    { 
     value *= -1; 
    } 

    while (i < value) 
    { 
     count++; 
     i *= 10; 
    } 

    if (count > 0) 
    { 
     return count; 
    } 
    else 
    { 
     return 1; 
    } 
} 

dodatkową szybkość, można nawet zastąpić mnożenia przez dziesięć z pewnym bitowym twiddling:

i = ((i << 2) + i) << 1; 

(Bit przesunięcie jest cool, ale mnożenie może być „wolna”, jeśli CPU przeprowadź rozmnażanie w jakiejś niewykorzystanej jednostce mnożenia - nowoczesne procesory są rzeczą piękną).