Reputation: 29
I have hit a bit of a roadblock and I was hoping someone could help.
Suppose you have:
int A[]={156,23,212,4,12};
And you would like to append it to give a single integer n=15623212412
How can I fix my code to do so?
int p, n=0, size=5;
for(i=1;i<size;i++){
p=10;
while(A[i]>=p)
p*=10;
n*=p;
n+=A[i];
}
It needs to be in C and it needs to create integer n through a loop as the integers in and size of the array will change.
Upvotes: 1
Views: 12914
Reputation: 81
You can first convert the integer array to string and then can convert it into a single integer, like this:
std::ostringstream os;
for (int i: res) {
os << i;
}
std::string str(os.str());
stringstream geek(str);
int x = 0;
geek >> x;
where res
is an array.
Upvotes: 0
Reputation: 41794
You can try using a lookup table for powers of 10
const uint64_t powersOf10[] = { // use lookup to reduce multiplications
1, 10,
100, 1000,
10000, 100000,
1000000, 10000000,
100000000, 1000000000, // the table can end here if A[i] is of type int
10000000000, 100000000000,
1000000000000, 10000000000000,
100000000000000, 1000000000000000,
10000000000000000, 100000000000000000,
1000000000000000000, 10000000000000000000
};
int A[] = {156, 23, 212, 4, 12};
uint64_t *p10, n = 0; // or unsigned long long if uint64_t not available
for (int i = 0; i < sizeof(A)/sizeof(A[0]); i++)
{
// get the length of A[i] by linear search
p10 = powersOf10;
while (*p10 < A[i]) p10++;
n *= *p10;
n += A[i];
}
You can change the linear search to a binary search, or using some optimized way to calculate log10
to get the index to powersOf10[]
If you just want to print then the simplest solution would be using sprintf
. It'll work for arbitrarily long arrays
char output[MAX], *pos = output;
for (int i = 0; i < sizeof(A)/sizeof(A[0]); i++)
pos += sprintf(pos, "%d", A[i]);
Upvotes: 0
Reputation: 453
There are a lot of good answers here, but I also like converting to string, then to a long long int. That was mentioned above, but let me add an implementation. It is simpler than some alternatives:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int A[] = {156, 23, 212, 4, 12};
int length = 5;
char a_as_num[length][4];
char string[15] = "\0";
long long number;
int i;
for (i = 0; i < length; i++) {
sprintf(a_as_num[i], "%d", A[i]);
strcat(string, a_as_num[i]);
}
number = atoll(string);
printf("%lli\n", number);
return 0;
}
Upvotes: 0
Reputation: 15827
I suggest this approach given that you know beforehand you're not going to overflow...
I'm using long
as they are 64 bits on my architecture (they are treated as long long
)
If it's not your case use long long
long A[]={156,23,212,4,12};
long size = 5;
long i;
long j;
long n;
long k;
i = size;
j = 0;
n = 0;
k = 1;
while( true )
{
if( j == 0 )
{
i--;
if( i < 0 )
{
break;
}
j = A[ i ];
}
n += ( j % 10 ) * k;
j /= 10;
k *= 10;
}
printf("%ld\n", n); // <== final result printed
Upvotes: 0
Reputation: 93476
If the size of the array can be bigger you have to understand that a 32 bit integer is good for only nine decimal digits - log10(232), and that even a 64 bit integer is good for 19 decimal digits - log10(264). Either way, even your small example will not fit in a 32 bit int
.
Also there is no real mathematical purpose or relationship in appending arbitrary integers in this way, especially as each has a variable number of decimal significant digits - any algorithm would have to take that into account.
So for the reasons given, attempting to solve the problem arithmetically is both over complex and inflexible; the simpler solution is to generate the result as a string.
int A[]={156,23,212,4,12};
int i = 0 ;
int index = 0 ;
const int length_A = sizeof(A) / sizeof(*A) ;
char astr[length_A * 10 ] ; // sized to accommodate worst case
// string length for 32 bit int of INT_MAX.
for( i = 0; i < length_A; i++ )
{
index += sprintf( &astr[index], "%d", A[i] ) ;
}
printf( "%s", astr ) ;
If you really need an arithmetic solution and can work within the limits of the available integer data types, then I suggest that you use unsigned long long
for the output and unsigned int
for the input, then:
#include <stdio.h>
#include <math.h>
int main()
{
unsigned int A[]={156,23,212,4,12};
unsigned long long result = 0 ;
int i = 0 ;
const int length_A = sizeof(A) / sizeof(*A) ;
for( i = 0; i < length_A; i++ )
{
result += A[i] ;
if( i < length_A - 1)
{
int digits = (int)ceil( log10( (double)A[i+1] ) ) ;
result *= (int)pow( 10, digits ) ;
}
}
printf( "%llu\n", result ) ;
return 0 ;
}
Upvotes: 1
Reputation: 206577
I see couple of problems:
You are starting the for
loop with i=1
. It should be i=0
.
15623212412
could be too big to fit in an int
. It is on my machine. Use long
or a bigger integral type.
By the way, I was able to detect the problem by adding a printf
.
#include <stdio.h>
int main()
{
int A[]={156,23,212,4,12};
int p, size=5;
long n = 0;
int i;
for(i=0;i<size;i++){
p=10;
while(A[i]>=p)
p*=10;
n*=p;
n+=A[i];
printf("n: %ld\n", n);
}
return 0;
}
Upvotes: 0