Разделить целое число на два отдельных целых числа
предположим, что я
int n=123456;
int x,y=0;
как разбить целое число " n " на две половины.
Примечание : общее количество цифр в n
всегда будет кратно 2, например 1234, 4567, 234567, 345621 etc... все 2,4,6,8 цифр.
Я хочу разделить их пополам.
Я пытаюсь со следующим кодом, но он не работает,y
переменная держит обращенную вторую часть как-то.
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);
при входе :
n=123456;
вывод, который я получаю:
Первая Половина = 123
Вторая Половина = 654
выход я хочу :
Первый Тайм: 123
Вторая Половина : 456
7 ответов
вот показательная программа. Он не использует никаких функций, кроме printf.:) Так это самое простое решение.
#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 );
}
}
выход программы
1 2
12 34
123 456
1234 5678
12345 67890
если вы собираетесь использовать тип знакового целого числа и отрицательные числа, то программа может выглядеть следующим образом
#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 );
}
}
его выход составляет
-1 -2
12 34
-123 -456
1234 5678
-12345 -67890
вот на самом деле, что я бы сделал
#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);
}
Это можно сделать путем деления операторов модуля с делителем, то есть 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;
}
другая возможность:
// 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;
}
, который производит вывод
iVal iTop iBot
00123456 00000123 00000456
00012345 00000012 00000345
00000012 00000001 00000002
00000000 00000000 00000000
1234567890 00012345 00067890
-1234567890 -00012345 -00067890
самый простой способ сделать это с помощью тега sprintf. Это принимает значение и форматирует его в соответствии с предоставленным спецификатором. После того, как целое число представлено в виде строки, вы просто берете каждую половину строки. Используя использования sscanf, вы обращаете процесс назад к integer.
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] = '';
sscanf(tmp, "%d", &a); // gets the first half
strncpy(tmp, &(str[len/2]), len/2); // copies from the middle of str
tmp[len/2] = '';
sscanf(tmp, "%d", &b); // gets the second half
}
еще один вариант использования строк для разделения:
#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 );
}
некоторые примеры выполнения:
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 1
USAGE: ./splitter integer_value_with_even_number_of_digits
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 12
val: 12, lo: 1, hi: 2
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter -12
val: -12, lo: 1, hi: 2
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter -123
USAGE: ./splitter integer_value_with_even_number_of_digits
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter -1234
val: -1234, lo: 12, hi: 34
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 12345678
val: 12345678, lo: 1234, hi: 5678
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter -1234567890
val: -1234567890, lo: 12345, hi: 67890
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 012
val: 12, lo: 1, hi: 2
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 00123456
val: 123456, lo: 123, hi: 456
[fbgo448@n9dvap997]~/prototypes/splitter: ./splitter 001234567
USAGE: ./splitter integer_value_with_even_number_of_digits
вы не упомянули, должны ли значения быть положительными или нет, или количество ведущих нулей против количества цифр (поскольку оно читается как целое значение, а не строка, после преобразования нет ведущих нулей).
для меня, этот код имеет силу простоты. Мы по существу рассматриваем число как строку цифр для разделения посередине, поэтому (по крайней мере, на мой взгляд), использование строковых операций казалось наиболее простым. Производительность, это не должно быть медленнее, чем использование log
, чтобы получить цифры и цикл через них.
поскольку это проблема с числами, более конкретно целыми числами, вы не должны использовать ни строки, ни операции с плавающей запятой.
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;
}
здесь n
содержит верхнюю половину цифр, lower_half
нижние.