2015-08-14 24 views
8

Supponiamo che io sonoSplit intero in due interi separati

int n=123456; 
int x,y=0; 

Come faccio a dividere l'intero "n" in due metà.

Nota: il numero totale di cifre in n sarà sempre multiplo di 2, ad es. 1234, 4567, 234567, 345621 ecc ... tutti hanno 2,4,6,8 cifre. Voglio dividerli a metà.

Sto provando con il seguente codice ma non funziona, la variabile trattiene in qualche modo la seconda parte invertita.

int x, y=0, len, digit; 
int n=123456; 

len=floor(log10(abs(n))) + 1; 
x=n; 
while((floor(log10(abs(x))) + 1)>len/2) 
{ 
    digit=x%10; 
    x=x/10; 
    y=(y*10)+digit; 
} 
printf("First Half = %d",x); 
printf("\nSecond Half = %d",y); 

Quando l'ingresso è:

n = 123456;

uscita sto ottenendo:

'Primo tempo = 123
Secondo tempo = 654

uscita che voglio:

primo tempo: 123

Secon d Mezzo: 456

+0

Per favore guidami, non possiamo fare qualcosa del genere? \t prima convertire int in stringa tramite sprintf e quindi sottostringa e quindi riconvertire in int ?? Come fare questo ? – Prateek

+0

La tua domanda è molto poco chiara. Forse se lo fai bene, troverai già la risposta da solo. – Olaf

+1

Ho detto il numero di cifre nel numero .. entrambi hanno 4 e 6 cifre che sono multipli di 2 – Prateek

risposta

9

Ecco un programma dimostrativo. Non usa alcuna funzione tranne printf. :) Quindi è la soluzione più semplice.

#include <stdio.h> 

int main(void) 
{ 
    unsigned int a[] = { 12, 1234, 123456, 12345678, 1234567890 }; 
    const unsigned int Base = 10; 

    for (size_t i = 0; i < sizeof(a)/sizeof(*a); i++) 
    { 
     unsigned int divisor = Base; 
     while (a[i]/divisor > divisor) divisor *= Base; 

     printf("%u\t%u\n", a[i]/divisor, a[i] % divisor); 
    }   
} 

L'output del programma è

1  2 
12  34 
123  456 
1234 5678 
12345 67890 

Se avete intenzione di utilizzare un tipo intero con segno e numeri negativi quindi il programma può guardare il modo seguente

#include <stdio.h> 

int main(void) 
{ 
    int a[] = { -12, 1234, -123456, 12345678, -1234567890 }; 
    const int Base = 10; 

    for (size_t i = 0; i < sizeof(a)/sizeof(*a); i++) 
    { 
     int divisor = Base; 
     while (a[i]/(a[i] < 0 ? -divisor : divisor) > divisor) divisor *= Base; 

     printf("%d\t%d\n", a[i]/divisor, a[i] % divisor); 
    }   
} 

la sua uscita è

-1  -2 
12  34 
-123 -456 
1234 5678 
-12345 -67890 
+0

difficile da argomentare contro questa risposta come ottimale, dalla maggior parte degli angoli – mfrankli

2

Qui è in realtà quello che vorrei fare

#include <stdio.h> 
#include <math.h> 

int main(void) 
{ 
    int x, y=0, len, digit; 
    int n=123456; 

    len=floor(log10(abs(n))) + 1; 
    x = n/pow(10, len/2); 
    y = n - x * pow(10, len/2; 
    printf("First Half = %d",x); 
    printf("\nSecond Half = %d",y); 
} 
+0

Grazie ha fatto il mio lavoro :) Sei il migliore ... grazie mille .. Dio vi benedica – Prateek

+3

In realtà, operare su valori a virgola mobile è piuttosto scarso soluzione quando il problema riguarda gli interi. –

+0

Hai modificato il tuo primo codice :), il tuo primo codice è stato migliore di invertire nuovamente la stringa .. è un po 'lungo .. Perché hai rimosso il tuo primo codice bro? funzionava bene ... – Prateek

0

Il modo più semplice per farlo è con la funzione sprintf. Questo prende un valore e lo formatta in base allo specificatore fornito. Una volta che il tuo intero è rappresentato come una stringa, prendi semplicemente ogni metà della tua stringa. Usando sscanf, si inverte il processo in intero.

void print_both_halves(int x) { 
    char str[80]; // magic number lengths 
    char tmp[80]; 
    int len; 
    int a, b; 

    len = sprintf(str, "%d", x); // returns the number of chars written 

    strncpy(tmp, str, len/2); 
    tmp[len/2] = '\0'; 
    sscanf(tmp, "%d", &a); // gets the first half 

    strncpy(tmp, &(str[len/2]), len/2); // copies from the middle of str 
    tmp[len/2] = '\0'; 
    sscanf(tmp, "%d", &b); // gets the second half 
} 
+0

Grazie ma nel tuo codice tmp è un tipo di dati stringa e voglio il risultante nel tipo di dati intero in modo che possa fare più calcoli in seguito – Prateek

+0

Usa atoi() per convertire le due stringhe in un intero –

+1

questo è un problema di numeri, tu non dovrebbe usare stringhe per risolverlo. –

-1

Poiché questo sembra essere un problema con i numeri, in particolare gli integer, non si dovrebbero usare stringhe o operazioni in virgola mobile.

int n = 123456; 

int digits = 0; 
int m = n; 
while (m) { 
    digits++; 
    m /= 10; 
} 

digits /= 2; 
int tmp = 0, lower_half = 0; 
while (digits--) { 
    tmp *= 10; 
    tmp += n % 10; 
    n /= 10; 
} 

while (tmp) { 
    lower_half *= 10; 
    lower_half += tmp % 10; 
    tmp /= 10; 
} 

Qui, n contiene la metà superiore delle cifre, lower_half quelli inferiori.

+0

Perché il downvote? –

2

Questa operazione può essere eseguita dividendo un operatore modulo con il divisore, ovvero 10 (NumberOfDigits/2).

#include <stdio.h> 

int getNumberOfDigits(int n) 
{ 
    int counter = 0; 
    for (; n > 0; n /= 10) 
     counter++; 
    return counter; 
} 

int main(void) 
{ 
    int n = 123456; 

    int divider = 1; 
    for (int i = 0; i < getNumberOfDigits(n)/2; i++) { 
     divider *= 10; 
    } 
    printf("%d, %d\n", n/divider, n % divider); 

    return 0; 
} 
1

Altra possibilità:

// split an int value into two pieces with the same number of decimal 
// digits in each piece. a couple of examples to demonstrate the output 
//  iVal   iTop   iBot 
//  1234   12    34 
// 123456   123   456 
void split_int (int iVal, int *iTop, int *iBot) 
{ 
    int iTopx = iVal; // save a copy of the value to be split later 

    // start with assuming two decimal digits. if value is zero will still work. 
    // we will then keep shifting the value right by two decimal digits as 
    // we increment our divisor by one decimal digit so that we can create 
    // a divisor we can then use to split the value using integer division 
    // to get the top half and remainder of integer division for the bottom half. 

    int iTen = 10; // divisor value to split two decimal digits 
    iVal /= 100;  // shift value right by two decimal digits 
    while (iVal) { // check to see if we are done, if not continue counting 
     iTen *= 10; // increase the divisor value we will use to split digits 
     iVal /= 100; // shift value right by two decimal digits 
    } 

    *iTop = iTopx/iTen; // split off top part by dividing by divisor 
    *iBot = iTopx % iTen; // split off bottom part by taking remainder 
} 

// test harness for the function above to try out several input data variations 
// and print the results. This is a Visual Studio Windows Console Application 
// so the entry point is _tmain(). 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int iTop, iBot, iVal; 

    printf (" iVal  iTop  iBot\n"); // output heading 

    split_int ((iVal = 123456), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    split_int ((iVal = 12345), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    split_int ((iVal = 12), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    split_int ((iVal = 0), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    split_int ((iVal = 1234567890), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    split_int ((iVal = -1234567890), &iTop, &iBot); 
    printf (" %8.8d %8.8d %8.8d\n", iVal, iTop, iBot); 

    return 0; 
} 

che produce l'uscita di

iVal  iTop  iBot 
    0
    00
    00000012 00000001 00000002 
    00000000 00000000 00000000 
    1234567890 00
    -1234567890 -00-00067890 
0

Un'altra variazione sul utilizzando stringhe per fare la scissione:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int split(int val, int *top, int *bot) 
{ 
    char tmp[23]; // should be large enough to hold a 64-bit decimal integer 
       // plus sign plus 0 terminator 
    char low[12] = {0}; 
    char high[12] = {0}; 

    if (val < 0) 
    val = -val; 

    sprintf(tmp, "%d", val); 
    if (strlen(tmp) % 2) 
    return 0; 

    strncpy(low, tmp, strlen(tmp)/2); 
    strncpy(high, tmp + strlen(tmp)/2, strlen(tmp)/2); 

    *top = (int) strtol(low, NULL, 10); 
    *bot = (int) strtol(high, NULL, 10); 

    return val; 
} 

int main(int argc, char **argv) 
{ 
    if (argc < 2) 
    { 
    fprintf(stderr, "USAGE: %s integer_value_with_even_number_of_digits\n", argv[0]); 
    exit(0); 
    } 

    int val = (int) strtol(argv[1], NULL, 10); 
    int lo, hi; 

    if (split(val, &lo, &hi)) 
    printf("val: %d, lo: %d, hi: %d\n", val, lo, hi); 
    else 
    fprintf(stderr, "USAGE: %s integer_value_with_even_number_of_digits\n", argv[0]); 

    exit(0); 
} 

alcune piste di esempio:

[[email protected]]~/prototypes/splitter: ./splitter 1 
USAGE: ./splitter integer_value_with_even_number_of_digits 
[[email protected]]~/prototypes/splitter: ./splitter 12 
val: 12, lo: 1, hi: 2 
[[email protected]]~/prototypes/splitter: ./splitter -12 
val: -12, lo: 1, hi: 2 
[[email protected]]~/prototypes/splitter: ./splitter -123 
USAGE: ./splitter integer_value_with_even_number_of_digits 
[[email protected]]~/prototypes/splitter: ./splitter -1234 
val: -1234, lo: 12, hi: 34 
[[email protected]]~/prototypes/splitter: ./splitter 12345678 
val: 12345678, lo: 1234, hi: 5678 
[[email protected]]~/prototypes/splitter: ./splitter -1234567890 
val: -1234567890, lo: 12345, hi: 67890 
[[email protected]]~/prototypes/splitter: ./splitter 012 
val: 12, lo: 1, hi: 2 
[[email protected]]~/prototypes/splitter: ./splitter 0
val: 123456, lo: 123, hi: 456 
[[email protected]]~/prototypes/splitter: ./splitter 0
USAGE: ./splitter integer_value_with_even_number_of_digits 

Lei non ha menzionato se i valori dovessero essere positivi o no, o se gli zeri contano il numero di cifre (dal momento che è letta come un valore intero e non una stringa, non ci sono zeri iniziali dopo la conversione).

Per me, questo codice ha il pregio della semplicità. Stiamo essenzialmente trattando il numero come una stringa di cifre da suddividere in mezzo, quindi (almeno nella mia mente), l'uso delle stringhe mi è sembrato il più semplice. Per quanto riguarda le prestazioni, questo non dovrebbe essere più lento dell'utilizzo di log per ottenere le cifre e il loro ciclo.