Recursive program for counting 1 bits in integer - c

I wrote an iterative program that counts of the amount of 1s in the binary of an integer given in argv[1], my iterative version worked fine but I'm having trouble figuring out how to make the function recursive.
I've tried changing the function with an if statement
#include <stdio.h>
#include <stdlib.h>
int bitcount( int x ) {
unsigned int count = 0 ;
count += x & 1;
x >>= 1 ;
if ( x > 0 ) {
bitcount( x ) ;
}
return count ;
}
int main( int argc, char *argv[] ) {
int b ;
b = atoi( argv[1] ) ;
b = bitcount ( b ) ;
printf( "%d\n", b ) ;
return 0 ;
}
My iterative program gave me the correct answer, but this program will print 1 no matter what number I use.

The problem is that you're not using the returned value of your bitcount function. Change
bitcount( x ) ; for count += bitcount( x ) ;

Related

Why my number to string converter keeps returning 000?

I have a issue with my number to string implemention. For some reason I keep getting 000 on my terminal even though. I couldn't find a solution, what is the potantial issue here?
Im now sure my code is broken but don't really see the problem.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
/* public domain code feel free to use as what you wish, no warranties given*/
char finddigits(unsigned n) {
char base = 6;
unsigned tester = 100000;
while(base % tester != 0) {
base--;
/* inefficient but works for now */
switch(tester) {
case 100000:
tester = 10000;
break;
case 10000:
tester = 1000;
break;
case 1000:
tester = 100;
break;
case 100:
tester = 10;
break;
case 10:
tester = 1;
break;
}
}
return base;
}
char* num2str(unsigned n) {
char size = finddigits(n);
char* tempbuf = malloc(size);
*tempbuf = 48 + (n / pow(10, size));
for(unsigned int i = 1; i < size; i++)
*(tempbuf + i) = 48 + (n % (10 * i));
return tempbuf;
}
int main(int argc, char* argv[]) {
int numbr = 210;
printf("%s \n", num2str(numbr));
/* expected 210 on string got 000 */
return 0;
}
You just want num2str to return the digit string for n.
A few issues:
finddigits is supposed to calculate the number of digits in n. But, [if it works at all], it uses an algorithm I've never seen.
finddigits isn't needed in num2str as num2str can be [much] simpler by filling the buffer in the reverse direction.
num2str is too complicated.
Calling num2str from printf leaks memory from the num2str call to malloc
Here's a refactored version:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char
finddigits(unsigned n)
{
int count = 0;
if (n == 0)
count = 1;
for (; n != 0; n /= 10, ++count);
return count;
}
char *
num2str(unsigned n)
{
static char buf[100];
char *dst = &buf[sizeof(buf) - 1];
// add string terminator
*dst-- = 0;
// we must always output a 0
if (n == 0)
*dst-- = '0';
// work backwards in the array
for (; n != 0; n /= 10, --dst)
*dst = (n % 10) + '0';
// point to first digit in string
dst += 1;
return dst;
}
void
dotest(unsigned n)
{
printf("n=%u '%s'\n",n,num2str(n));
}
int
main(int argc, char *argv[])
{
dotest(210);
dotest(0);
dotest(12345);
return 0;
}
Here's the program output:
n=210 '210'
n=0 '0'
n=12345 '12345'
The computer does what you told it to do, which is to say, it does complete nonsense.
finddigits(210) returns 1, because 6 % 100000 isn't 0 (it's 6), 5%10000 isn't 0 (it's 5), 4 % 1000 isn't 0 (it's 4), 3 % 100 isn't 0 (it's 3), 2 % 10 isn't 0 (it's 2), but 1 % 1 is 0 so the loop stops and the function returns 1.
Then, num2str allocates 1 byte. In this 1 byte, it sets the first byte to 48 + (210 / 10) which is 69, ASCII code for the letter E. Since size is 1 the loop doesn't run at all and num2str returns this allocation. When you print it, it prints the letter E - possibly with more gibberish after it since the string is not terminated, although for me it just printed E.
I have no idea how you managed to get 000.
You need to write code that tells the computer to do what you want it to do. When you can't get it to do what you want it to, for one part of the code, don't just skip that part of the code and go onto the next one. It all has to be right or it won't work.
Mathematics is also "public domain". Here are two versions of one of your functions, shown with a main() that tests both versions with several values.
Don't convert a signed integer value to unsigned for no particular reason. If you need/want the absolute value of a (possibly) negative number, C provides a function to achieve that.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int finddigits1( int n ) {
int count = n == 0; // ensure 0 is counted as 1 digit
while( n ) count++, n /= 10;
return count;
}
int finddigits2( int n ) {
// log of zero is undefined
return ( n == 0 ) ? 1 : (int)log10(abs(n))+1;
}
char *num2str( int n, char buf[] ) {
printf( "finddigits1( %d ) counted %d\n", n, finddigits1( n ) );
printf( "finddigits2( %d ) returns %d\n", n, finddigits2( n ) );
strcpy( buf, "Hello world!" ); // Left as an exercise to fix your own code
return buf; // returning allows direct usage by caller
}
int main() {
int tests[] = { 123, -123, 0, 100, 54321 };
char buf[ 30 ]; // better to pass large buffer to function than use malloc()
for( int i = 0; i < sizeof tests/sizeof tests[0]; i++ ) {
int n = tests[i];
printf( "n = %d '%s'\n", n, num2str( n, buf ) );
}
return 0;
}
finddigits1( 123 ) counted 3
finddigits2( 123 ) returns 3
n = 123 'Hello world!'
finddigits1( -123 ) counted 3 // NB: Account for negative sign!
finddigits2( -123 ) returns 3
n = -123 'Hello world!'
finddigits1( 0 ) counted 1
finddigits2( 0 ) returns 1
n = 0 'Hello world!'
finddigits1( 100 ) counted 3
finddigits2( 100 ) returns 3
n = 100 'Hello world!'
finddigits1( 54321 ) counted 5
finddigits2( 54321 ) returns 5
n = 54321 'Hello world!'
If you're trying to convert a number to a string, why not just use sprintf()?
See here:
How to convert an int to string in C?

How to calculate how many times a function is inside another function, for example g(9) inside g(k)

I am performing an activity, which is based on the recursive function, but I cannot understand how to put a part in code format. The code is this :
#include <stdio.h>
int count;
int g( int x ) {
count++;
if ( x == 0 )
return 2;
if ( x <= 2 )
return x * x;
if ( x <= 5 )
return x * g( x - 1 );
return (g( x - 3 ) + g( x - 2 ) );
}
int main () {
int k = 15;// random number
count = 0;
printf( " g(%d) = %d\n", k, g( k ) );
printf( " count: %d\n", count);
printf( " g(9) appeared : %d time(s) inside g(%d)",...,k);// in this space would be the other variable
return 0;
}
What I don't understand is how to calculate how many times, for example g(9), appears inside g(k). I've already made some attempts, but it never arrives at what is really requested. Thanks in advance

Performance of n-section root finding algorithm

I wrote a n-section algorithm for finding roots of a function. The working principle is exactly the same as is bisection method, only the range is divided into N equal parts instead. This is my C code:
/*
Compile with: clang -O3 -o nsect nsect.c -Wall -DCOUNT=5000000 -DNSECT=? -funroll-loops
*/
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#define N 6
#ifndef COUNT
#error COUNT not defined!
#endif
#ifndef NSECT
#define NSECT 2
#endif
float polynomial[N];
float horner( const float poly[N], float x )
{
float val = poly[N-1];
for ( int i = N - 2; i >= 0; i-- )
val = poly[i] + x * val;
return val;
}
float f( float x )
{
return horner( polynomial, x );
}
float nsect( float a, float b, const float eps_x )
{
float fa = f( a );
float fb = f( b );
if ( fa == 0 ) return a;
else if ( fb == 0 ) return b;
else if ( fa * fb > 0 ) return 0;
float x[NSECT];
float fx[NSECT];
while ( b - a > eps_x )
{
x[0] = a;
if ( ( fx[0] = f( x[0] ) ) == 0 ) return x[0];
int found = 0;
for ( int i = 0; i < NSECT - 1; i++ )
{
x[i + 1] = a + ( b - a ) * (float)( i + 1 ) / NSECT;
if ( ( fx[i + 1] = f( x[i + 1] ) ) == 0 )
return x[i + 1];
else if ( fx[i] * fx[i + 1] < 0 )
{
a = x[i];
b = x[i + 1];
found = 1;
break;
}
}
if ( !found )
a = x[NSECT - 1];
}
return ( a + b ) * 0.5f;
}
int main( int argc, char **argv )
{
struct timeval t0, t1;
float *polys = malloc( COUNT * sizeof( float ) * N );
float *p = polys;
for ( int i = 0; i < COUNT * N; i++ )
scanf( "%f", p++ );
float xsum = 0; // So the code isn't optimized when we don't print the roots
p = polys;
gettimeofday( &t0, NULL );
for ( int i = 0; i < COUNT; i++, p += N )
{
memcpy( polynomial, p, N * sizeof( float ) );
float x = nsect( -100, 100, 1e-3 );
xsum += x;
#ifdef PRINT_ROOTS
fprintf( stderr, "%f\n", x );
#endif
}
gettimeofday( &t1, NULL );
fprintf( stderr, "xsum: %f\n", xsum );
printf( "%f ms\n", ( ( t1.tv_sec - t0.tv_sec ) * 1e6 + ( t1.tv_usec - t0.tv_usec ) ) * 1e-3 );
free( polys );
}
EDIT: This is the command I used to compile the code: clang -O3 -o nsect nsect.c -Wall -DCOUNT=5000000 -DNSECT=? -funroll-loops.
I ran everything on i7-8700k.
I decided to test the algorithm performance for different N values. The test consists of measuring time needed to find any root in range (-100;100) for each of 5,000,000 polynomials of degree 5. The polynomials are randomly generated and have real coefficients ranging from -5 to 5. The polynomial values are calculated using Horner's method.
These are results I got from running the code 10 times for each N (x=N, y=time [ms]):
My understanding of the worst case performance here is that the amount of work to be done in the main while loop is proportional to N. The main loop needs logN(C) (where C > 1 is a constant - ratio of initial search range to requested accuracy) iterations to complete. This yields following equation:
The plot looks very similar to the violet curve I used above to roughly match the data:
Now, I have some (hopefully correct) conclusions and questions:
Firstly, is my approach valid at all?
Does the function I came up with really describe the relation between number of operations and N?
I think this is the most interesting one - I'm wondering what causes such significant difference between N=2 and all the others? I consistently get this pattern for all my test data.
Moreover:
That function has minimum in e&approx;2.718..., which is closer to 3 than to 2. Also, f(3) < f(2) holds. Given that the equation I came up with is correct, I think that would imply that trisection method may actually be more efficient than bisection. It seems a bit counter intuitive, but the measurements seem to acknowledge that. Is this right?
If so, why does trisection method seem to be so unpopular compared to bisection?
Thank you
I am commenting on the general question, not on your particular code, which I don't fully understand.
Assuming that there is a single root known to be in an interval of length L and the desired accuracy is ε, you will need log(L/ε)/log(N) subdivision stages. Every subdivision stage requires N-1 evaluations of the function (not N), to tell which subinterval among N contains the root.
Hence, neglecting overhead, the total cost is proportional to (N-1)/log(N). The values of this ratio are, starting from N=2:
1.44, 1.82, 2.16, 2.49, 2.79...
and higher.
Hence the theoretical optimum is with N=2. This is why trisection is not used.

Palindromic numbers in C, string error

New to C. Trying to write program that prints out palindromic numbers < 1 million.
Prints out jibberish. Have I made an error with strings?
int decimal_pali(int x)
{
int digits=0;
int num=x;
char D[7];
while(num>0)
{
D[digits]=num%10;
digits+=1;
num/=10;
}
D[digits]='\0';
num=atoi(D);
if(num == x)
{
return 1;
}
return 0;
}
Your mistake lies here:
D[digits]=num%10;
It should be
D[digits] = num%10 + '0';
num % 10 will result in a number between 0 and 9 inclusive but since you are working with characters, you need to get the ASCII value of the digit. If you have a look at the ASCII table, you'll find that in order to achieve what you want, you need to add the ASCII value of '0' (48) to the value to get the correct character.
Curiosity wouldn't let me resist the "more than one base" thing, though I doubt the result has any (non-trivial) number-theoretic significance. Anyway, here's the code, and a sample run below that...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( int argc, char *argv[] ) {
int n1 = ( argc>1? atoi(argv[1]) : 1 ),
n2 = ( argc>2? atoi(argv[2]) : 999 ),
b1 = ( argc>3? atoi(argv[3]) : 10 ),
b2 = ( argc>4? atoi(argv[4]) : 10 );
int n=n1, b=b1, ispal();
char *itoa();
for ( n=n1; n<=n2; n++ ) {
for ( b=b1; b<=b2; b++ ) if ( !ispal(n,b) ) goto next_n;
printf("%10d(base10)",n);
for ( b=b1; b<=b2; b++ ) printf(" = %s(%d)", itoa(n,b),b);
printf("\n");
next_n: ; }
} /* --- end-of-function main() --- */
int ispal ( int i, int base ) {
char *itoa(), *a=itoa(i,base);
int answer=0, k=0,n=strlen(a);
if ( n > 1 ) {
for ( k=0; k<n/2; k++ )
if ( a[k] != a[n-k-1] ) goto end_of_job;
answer = 1; }
end_of_job: return ( answer );
} /* --- end-of-function ispal() --- */
char *itoa ( int i, int base ) {
static char a[99], digits[99] = /* up to base 65 */
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$*";
int n = 0;
while ( 1 ) {
a[n++] = digits[i%base];
if ( (i/=base) < 1 ) break; }
a[n] = '\000';
return ( a );
} /* --- end-of-function itoa() --- */
I called it palinum.c, and a typical run gives...
bash-4.3$ ./palinum 1 9999999 3 4
10(base10) = 101(3) = 22(4)
130(base10) = 11211(3) = 2002(4)
11950(base10) = 121101121(3) = 2322232(4)
175850(base10) = 22221012222(3) = 222323222(4)
749470(base10) = 1102002002011(3) = 2312332132(4)
1181729(base10) = 2020001000202(3) = 10200200201(4)
showing just a few numbers between 1 and 10million that are "palindromic" in both base 3 and base 4. The few other tests I did showed nothing simultaneously palindromic in three consecutive bases. But the program's easily changed to permit any set of (non-consecutive) bases. (For a less trivial programming challenge, try multiple threads for several n's at a time.)

Fastest and most efficient way to find the maximum no. that can be obtained by performing bitwise and on 2 DISTINCT elements of array

Given an array of non-negative integers, what is the fastest and most efficient way to find the maximum no. that can be obtained by performing bitwise and (i.e, & operator) on 2 DISTINCT elements of the array?
This is my code until now :
max = 0
for(i=0; i<n; i++)
{
for(j=i+1; j<n; j++)
{
temp = a[i] & a[j];
if(temp > max)
max = temp
}
}
This, of course, is the naive method. I am looking for a more efficient solution.
Maybe something like using a trie(actually a binary tree) to find max XOR of elements of array. The description for the max XOR solution can be found at http://threads-iiith.quora.com/Tutorial-on-Trie-and-example-problems?share=1
I hope I have got the question right. Here's my solution to it:
You have an array of integers, say that they are unsigned integers since we are dealing with bitwise operations. Let's think of them as a string of zeroes and ones in their binary representation and then put them on top of each other.
We now have their corresponding bits aligned vertically. Let's draw vertical lines, starting from the leftmost column. If we ever encounter more than or equal to two 1s in a column, then rule out every row that does not have the 1s. We are to disregard the ruled out ones while drawing our further vertical lines.
You see where this is going at?
This shall go on until we have only and exactly 2 lines left that hasn't been ruled out. If we ever end up with anything else than 2, then it means something went wrong:
Less than 2 means we had less than 2 lines initially
More than 2 means that...
If there are less than what we had initially, then the ones left should all be identical
If there are exactly as many as we had initially, then it can be that all are the same, or every possible pair is bitwise distinct, meaning that every single pair produces 0
Here's the code I've written that follows the logic I've described above:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <memory.h>
#define bit(_x_) (1U << (_x_))
void randomfillarray( unsigned int * arr, size_t size ) {
srand( time( NULL ) );
for ( int i = 0; i < size; i++ )
arr[i] = rand( );
}
int main( ) {
unsigned int arr[10];
size_t size = sizeof arr / sizeof * arr;
randomfillarray( arr, size );
unsigned int * resultantcouple = malloc( sizeof arr );
memcpy( resultantcouple, arr, sizeof arr );
for ( int i = 0; i < size; i++ )
printf( i ? " %u" : "%u", arr[i] );
putchar( '\n' );
int success = 0;
for ( unsigned int thebit = bit( sizeof( int ) * 8 - 1 ); thebit; thebit >>= 1 ) {
int count = 0;
int * indices = NULL;
for ( int i = 0; i < size; i++ ) {
if ( resultantcouple[i] & thebit ) {
indices = realloc( indices, ++count * sizeof * indices );
indices[count - 1] = i;
}
}
if ( count >= 2 ) {
size = count;
for ( int i = 0; i < size; i++ )
resultantcouple[i] = resultantcouple[indices[i]];
resultantcouple = realloc( resultantcouple, size * sizeof * resultantcouple );
}
if ( size == 2 ) {
success = 1;
break;
}
free( indices );
}
if ( success )
printf( "Success! %u and %u are the ones.", resultantcouple[0], resultantcouple[1] );
else
printf( "Failure! Either all pairs are bitwise distinct, or there are less than 2 elements, or something else..." );
putchar( '\n' );
return 0;
}
Here's the same during action: http://ideone.com/hRA8tn
I'm not sure if this is the best, but it should be better than testing all out.
First look at and understand the heapsort algorithm.
Turn the array into a heap which lets you access the two largest elements. This is done in linear time, O (n).
Take the two largest elements, x = largest, y = second largest. If y = 0, the solution is 0. If the highest bit in x and the highest bit in y are the same, the solution is x & y. Otherwise, clear the highest bit in x, fix the heap, and try again. The last step takes O (log n) steps, and if you are using k bit integers, like 32 or 64, it is repeated at most k times.
No extra space needed, and linear time.
Pseudo-code:
If n ≤ 1 there is no solution.
Turn a [0] to a [n-1] into a heap with a [0] as the largest element.
Repeat
Let x = a [0].
Let y = a [1].
If n ≥ 3 and a [2] > a [1] then let y = a [2].
If y = 0 then the solution is 0.
Determine b = the highest bit of x.
If (y & b) != 0 then the solution is x & y.
Replace a [0] with x & (~ b)
Turn a [0] to a [n-1] into a heap again by moving a [0] down.
This assumes that a [i] and a [j] are considered "distinct array elements" if i ≠ j. If you require instead that a [i] ≠ a [j] then things are slightly different. You'd have to remove duplicate entries in your array, but in case the largest elements are for example 31 and 15, you don't want to clear the highest bit in 31 and then remove it as a duplicate! So the code is more difficult.
Let mask = ~0. In the following, when creating a heap compare a [i] & mask, not a [i].
Turn a [0] to a [n-1] into a heap with a [0] as the largest element.
Repeat
If n ≤ 1 then there is no solution.
Let x = a [0].
Let y = a [1].
If n ≥ 3 and a [2] & mask > y & mask then let y = a [2].
If x = y then let n = n - 1, let a [0] = a [n], restore the heap, and continue.
If (y & mask) = 0 then the solution is 0.
Determine b = the highest bit of x & mask.
If (y & b) != 0 then the solution is x & y.
Replace mask with mask & ~b.
Restore the heap and continue.
Worst case is O (n log n), for example if all elements are 1 except one that is 0.
The following worked for me for our_n uints in uint our_a[our_n], without changing the array or copying it or anything else. The essence is that in one pass down the array it identifies the next bit that can be added to the result so far. Each pass only considers values which contain all the bits of the result so far:
uint result ;
uint passes ;
uint msb ;
uint pn ;
at->start_clock = times(&at->start_tms) ;
result = 0 ;
passes = 0 ;
msb = (UINT_MAX >> 1) + 1 ;
pn = our_n ;
do
{
uint seen_once ;
uint seen_again ;
passes += 1 ;
seen_once = 0 ;
seen_again = 0 ;
for (uint i = 0 ; i < pn ; ++i)
{
uint a ;
a = our_a[i] ;
if ((a & result) == result)
{
seen_again |= (a & seen_once) ;
seen_once |= a ;
} ;
} ;
assert((seen_again & result) == result) ;
seen_again ^= result ;
while (msb > seen_again)
msb >>= 1 ;
result |= msb ;
}
while (msb > 1) ;
So, this is O(p * n), where p is the number of passes: 1..32.
If it is OK to destroy the contents of the array, then the inner loop can be changed to:
k = 0 ;
for (uint i = 0 ; i < pn ; ++i)
{
uint a ;
a = our_a[i] ;
if ((a & result) == result)
{
our_a[k++] = a ;
seen_again |= (a & seen_once) ;
seen_once |= a ;
} ;
} ;
pn = k ;
Of course, the first pass is now doing rather more work than it need to, so doing that separately saves a bit more.

Resources