假设我有
int n=123456;
int x,y=0;
如何将整数“n”分成两半。
注意:n
中的总位数将始终是2的倍数,例如 1234,4567,234567,35621等...都有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
答案 0 :(得分:11)
这是一个示范程序。它不使用除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
答案 1 :(得分:4)
这实际上是我要做的事情
#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);
}
答案 2 :(得分:3)
这可以通过将模数运算符除以除法器来完成,即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;
}
答案 3 :(得分:1)
另一种可能性:
// 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
答案 4 :(得分:0)
最简单的方法是使用sprintf功能。这将获取一个值并根据提供的说明符对其进行格式化。将整数表示为字符串后,只需取出字符串的每一半即可。使用sscanf,将进程反转回整数。
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
}
答案 5 :(得分:0)
使用字符串进行拆分的另一种变体:
#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
获取数字并循环遍历它们要慢。