2011-12-29 56 views

Trả lời

4

Trong phần sau tôi giả sử bạn có nghĩa là chữ số thập phân (cơ số 10). Có lẽ bạn có thể thích ứng với các giải pháp cho các hệ thống số khác bằng cách thay thế các số 10 s.

Lưu ý rằng hoạt động modulo là một điều phức tạp liên quan đến toán hạng âm. Vì vậy, tôi đã chọn kiểu dữ liệu là một số nguyên không dấu.

Nếu bạn muốn xử lý các chữ số đáng kể nhất đầu tiên, bạn có thể thử phương pháp chưa được kiểm tra sau:

uint32_t n = 1191223; 
do { 
    uint32_t digit = n%10; 
    // do something with digit 
} 
while (n/=10); 

Nếu bạn thích đi bộ qua các chữ số bắt đầu từ con số quan trọng nhất, bạn có thể thử để thích ứng mã chưa được kiểm tra sau:

uint32_t n = 1191223; 
#define MAX_DIGITS 10 // log10((double)UINT32_MAX)+1 
uint32_t div = pow(10, MAX_DIGITS); 

// skip the leading zero digits 
while (div && !(n/div)) div/=10; 
if (!div) div = 10; // allow n being zero 

do { 
    uint32_t digit = (n/div)%10; 
    // do something with digit 
} 
while (div/=10); 
0

Something như thế này:

char data[128]; 
int digits = 1191223; 
sprintf(data, "%d", digits); 
int length = strlen(data); 
for(int i = 0; i < length; i++) { 
    // iterate through each character representing a digit 
} 

Lưu ý rằng nếu bạn sử dụng số bát phân như 0100, bạn cũng cần phải thay đổi sprintf(data, "%d", digits); thành sprintf(data, "%o", digits);.

+0

Krister, Nếu chữ số của tôi bắt đầu bằng "0", nó cho tôi chiều dài sai, bạn có biết tại sao không? Btw folks thực sự thích tất cả các câu trả lời ở trên. – kforkarim

+0

@kforkarim - Tôi đã thêm bản cập nhật để xử lý số bát phân - số bắt đầu bằng '0' – Cyclonecode

3

Bạn muốn lặp qua các số 10 chữ số, nhưng một số nguyên không có khái niệm ký pháp và chữ số arabic. Chuyển đổi nó thành một chuỗi đầu tiên:

int i = 1191223; 
char buffer[16]; 
char *j; 
snprintf(buffer, 16, "%i", i); 
for (j = buffer; *j; ++j) { /* digit is in *j - '0' */ } 
+0

thiton Tôi chỉ tò mò bạn định nói gì ở đây là * j - '0', nó có tránh 0 đầu tiên không? Tôi đã cố gắng này với một số của 0191223 và chiều dài không đến được đúng, bất cứ đề nghị? – kforkarim

+1

@kforkarim có lẽ đó là chuyển đổi 'char2int':' uint32_t digit = * j-'0 '; '. Đảm bảo xử lý ''-'' chuỗi có thể chứa. – moooeeeep

0

Cách hack là chuyển đổi chuỗi này thành chuỗi (xem strtol) và sau đó chuyển thành số này. bạn có thể sử dụng giống như character you want - '0'

0

Off đỉnh đầu của tôi: "i% 100000", "i% 100000", ...

Một giải pháp đệ quy sẽ cho phép bạn bắt đầu từ "i% 10" .

1

Bạn có thể sử dụng sprintf() để chuyển đổi nó thành một mảng char, và sau đó lặp thông qua đó, như vậy (chưa được kiểm tra, chỉ để giúp bạn bắt đầu):

int a = 1191223; 
char arr[16]; 
int rc = sprintf(arr, "%d", a); 

if (rc < 0) { 
    // error 
} 

for (int i = 0; i < rc; i++) { 
    printf("digit %d = %d\n", i, arr[i]); 
} 
1
void access_digits(int n) 
{ 
     int digit; 
     if (n < 0) n = -n; 
     do { 
       digit = n % 10; 
       /* Here you can do whatever you 
        want to do with the digit */ 
     } while ((n/=10) > 0); 
} 
8

đạo, hoặc ngược?

Giả sử một số nguyên dương:

unsigned int n = 1191223; 

    while (n != 0) { 
     doSomething (n % 10); 
     n /= 10; 
    } 

... sẽ làm việc nhỏ nhất đến lớn nhất, hoặc ...

EDIT Tôi muốn quên tất cả về giải pháp này không làm việc tôi đã ở đây.Lưu ý rằng rất thông minh mọi người dường như sử dụng lặp đi lặp lại nhỏ nhất-to-lớn nhất (cả hạt nhân Linux và GL22 của GLibC printf, ví dụ, chỉ cần lặp lại) nhưng đây là một cách tệ hại để làm điều đó nếu bạn thực sự không muốn sử dụng snprintf đối với một số lý do ...

int left_to_right (unsigned int n) { 
    unsigned int digit = 0; 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    digit = pow(10, 1.0+ floor(log10(n))); 
    while (digit /= 10) { 
     doSomething ((n/digit) % 10); 
    } 
    } 
} 

tôi cho rằng nó rất ngớ ngẩn khi cho rằng bạn có log10pow nhưng không snprintf, vì vậy một kế hoạch thay thế sẽ là

int left_to_right_fixed_max (unsigned int n) { 
    unsigned int digit = 1000000000; /* make this very big */ 
    unsigned int n10 = 10 * n; 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    while (digit > n10) { digit /= 10; } 
    while (digit /= 10) { 
     doSomething ((n/digit) % 10); 
    } 
    } 
} 

... hoặc, nếu bạn thực sự don' t có phần cứng nhân/chia, bạn có thể sử dụng tại khả năng của mười.

int left_to_right (unsigned int n) { 
    static const unsigned int digit [] = 
    { 1, 
     10, 
     100, 
     1000, 
     10000, 
     100000, 
     1000000, 
     10000000, 
     100000000, 
     1000000000 /* make this very big */ 
    }; 
    static const unsigned char max_place = 10; 
    /* length of the above array */ 

    unsigned char decimal; 
    unsigned char place; 
    unsigned char significant = 0; /* boolean */ 

    if (0 == n) { 
    doSomething (0); 
    } else { 
    place = max_place; 
    while (place--) { 
     decimal = 0; 
     while (n >= digit[place]) { 
     decimal++; 
     n -= digit[place]; 
     } 
     if (decimal | significant) { 
     doSomething (decimal); 
     significant |= decimal; 
     } 
    } 
    } 
} 

… mà tôi đã thích nghi từ http://www.piclist.com/techref/language/ccpp/convertbase.htm thành phiên bản có mục đích chung hơn.

+0

Phiên bản đầu tiên của bạn là từ lùi về trước, cách bạn lấy các chữ số từ trước và lên như 1234> 1 2 3 và sau đó 4 thay vì 4 3 2 và 1 .. cảm ơn – kforkarim

+0

lặp lại hoạt động tốt cho chuyển tiếp nhưng bỏ qua 0, bất kỳ tại sao nó lại làm vậy? – kforkarim

+0

Wow, tôi chắc chắn tôi đã thực hiện một số giám sát ngu ngốc - Tôi sẽ xem xét tối nay. :-(Tôi ngu ngốc chỉ thử nó với "1191123!" – BRFennPocock

Các vấn đề liên quan