Time complexity of recursive solution to coin change - c

FROM HERE
Given a value N, if we want to make change for N cents, and we have
infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how
many ways can we make the change? The order of coins doesn’t matter.
For example, for N = 4 and S = {1,2,3}, there are four solutions:
{1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S
= {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.
Recursive solution. (Can someone please help me understand how to calculate time complexity of this solution)
How to solve T(M,N) = T(M,N-1) + T(M-1,N)
int count( int S[], int m, int n )
{
if (n == 0)
return 1;
if (n < 0)
return 0;
if (m <=0 && n >= 1)
return 0;
return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
}
int main()
{
int i, j;
int arr[] = {1, 2, 3};
int m = sizeof(arr)/sizeof(arr[0]);
printf("%d ", count(arr, m, 4));
getchar(); return 0;
}

Related

Permutations and 2d arrays

I want to check if three matrices A,B,C with same dimensions are permutations of each other(contain same elements with the same number of repetitions in every 2d array) and return 1 if they are and 0 if they are not. My code does not work properly; in this case it returns 1 1 1 1 instead of 1 0 1 0. I hope that you could help me with this.
#include <stdio.h>
#define MAX 100
int permutation (double A[100][100], double B[100][100], double C[100][100], int M, int N){
int i,j,x,y,true;
for(i=0;i<M;i++)
for(j=0;j<N;j++){
true=1;
for(x=0;x<M-i && true;x++)
for(y=0;y<N-j && true;y++)
if(A[i+x][j+y]!=B[i+x][j+y] || A[i+x][j+y]!=C[i+x][j+y])
true=0;
if(true) return 1;
}
return 0;
}
int main(){
double A[100][100] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
double B[100][100] = { {4, 1, 9}, {7, 8, 3}, {6, 2, 5} };
double C[100][100] = { {8, 4, 6}, {5, 2, 1}, {7, 9, 3} };
printf("%d ", permutation(A, B, C, 3, 3) );
C[2][2] = 1;
printf("%d ", permutation(A, B, C, 3, 3) );
C[1][2] = 3;
printf("%d ", permutation(A, B, C, 3, 3) );
B[2][2] = 10;
printf("%d ", permutation(A, B, C, 3, 3) );
}
I have edited this to remove my first attempt which worked for this particular example, but did not work in general (as pointed out in the comments, thanks). I will leave my second option.
My preferred solution is quite different than what you're currently doing so it might not be what you want, but in general I like the idea of simply sorting and doing a straight comparison.
// A comparison function to work with qsort from stdlib.h
// Like the original code, this checks for actual inequality, but when dealing with doubles you might want to look into using DBL_EPSILON from float.h
int doublecomp(const void *v1, const void *v2) {
double d1 = *(double *)v1;
double d2 = *(double *)v2;
if (d1 > d2) {
return 1;
}
if (d1 < d2) {
return -1;
}
return 0;
}
int permutation (double A[100][100], double B[100][100], double C[100][100], int M, int N) {
double ap[M*N]; // Assuming you have room on the stack for these. If M and N are expected to be large, put this on the heap instead
double bp[M*N];
double cp[M*N];
for (int i = 0; i < M; ++i) {
memcpy(ap + i * N, A[i], N * sizeof(ap[0]));
memcpy(bp + i * N, B[i], N * sizeof(bp[0]));
memcpy(cp + i * N, C[i], N * sizeof(cp[0]));
}
qsort(ap, M*N, sizeof(ap[0]), doublecomp);
qsort(bp, M*N, sizeof(bp[0]), doublecomp);
qsort(cp, M*N, sizeof(cp[0]), doublecomp);
return !(memcmp(ap, bp, M*N*sizeof(ap[0])) || memcmp(ap, cp, M*N*sizeof(ap[0])));
}
I find this nice to read. It handles arbitrary double values (you can adjust the comparison function based on your actual requirements, e.g. use DBL_EPSILON). And, assuming you might possibly have arbitrary doubles, this is probably as efficient as building some mapping for a histogram.
You could start by defining a function comparing the frequencies of the integers from two matrices.
bool is_permutation(int m1[][NUM_COLS], int m2[][NUM_COLS], int n)
{
int i, j, num1, num2;
int m1_counts[MAX_NUM] = {0};
int m2_counts[MAX_NUM] = {0};
for (i = 0; i < n; i++)
for (j = 0; j < NUM_COLS; j++) {
num1 = m1[i][j];
num2 = m2[i][j];
if (0 <= num1 && num1 < MAX_NUM &&
0 <= num2 && num2 < MAX_NUM) {
m1_counts[num1]++;
m2_counts[num2]++;
} else {
fprintf(stderr, "Error: out of bounds");
exit(EXIT_FAILURE);
}
}
for (i = 0; i < MAX_NUM; i++)
if (m1_counts[i] != m2_counts[i])
return false;
return true;
}
Using this approach you have a choice of either extending the function to include more matrices in its parameters. A simpler, yet less performant approach would be to just combine the results of multiple comparisons, which can be done with a macro.
#define ARE_PERMUTATIONS(m1, m2, m3, n) \
(is_permutation((m1), (m2), (n)) && \
is_permutation((m1), (m3), (n)) && \
is_permutation((m2), (m3), (n)))
Printing the results can be handled in a similar way.
#define PRINT_ARE_PERMUTATIONS(m1, m2, m3, n) \
printf(#m1 ", " #m2 ", and " #m3 " %s permutations\n", \
ARE_PERMUTATIONS((m1), (m2), (m3), (n)) ? \
"are" : "are not")
All that need be added to the main function are the following lines.
PRINT_ARE_PERMUTATIONS(m1, m2, m3, NUM_COLS);
m3[2][2] = 1;
PRINT_ARE_PERMUTATIONS(m1, m2, m3, NUM_COLS);
m3[1][2] = 3;
PRINT_ARE_PERMUTATIONS(m1, m2, m3, NUM_COLS);
m2[2][2] = 10;
PRINT_ARE_PERMUTATIONS(m1, m2, m3, NUM_COLS);

Recursively finding a sum of perfect squares in a list

I'm trying to recursively find a sum of perfect squares in a dynamically allocated list. For some reason, my function keeps overlooking the first element.
*A is the pointer to the first element of the array. n is the number of elements, meaning they are in range from 0 to n-1. When n is less than or equal to zero, n-1 isn't a valid index so I'm returning 0 to the sum of perfect squares.
int sum(int *A, int n)
{
int i, num = 0;
if (n <= 0)
return num;
for (i = 0; i < A[n - 1]; i++) {
if (i*i == A[n - 1]) {
num = A[n - 1];
}
}
return num + sum(A, n - 1);
}
Why does the first element always get overlooked? It works for all the other elements in the list.
EDIT: I've tried calling the function again and it seems that only number 1 got overlooked. That was fixed by modifying the for loop condition, so the solution would be:
int sum(int *A, int n)
{
int i, num = 0;
if (n <= 0)
return num;
for (i = 0; i <= A[n - 1]; i++) {
if (i*i == A[n - 1]) {
num = A[n - 1];
}
}
return num + sum(A, n - 1);
}
For starters as the array pointed to by A is not changed the pointer should be declared with the qualifier const.
Sizes of objects in C are estimated by using the type size_t. So the second parameter should be declared as having the type size_t.
Also the sum of perfect squares can be larger than an object of the type int can accomodate. So it is better to use the type long long int as the return type.
And if I am not mistaken 0 is not a perfect square. Though it is not very important nevertheless the loop can start with 1 instead of 0..
I can suggest the following solution.
#include <stdio.h>
long long int sum( const int *a, size_t n )
{
int perfect_square = 0;
if ( n )
{
int i = 1;
while ( i * i < a[n-1] ) i++;
if ( a[n-1] == i * i ) perfect_square = a[n-1];
}
return n == 0 ? perfect_square : perfect_square + sum( a, n -1 );
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
printf( "The sum of perfect squares is %lld\n", sum( a, N ) );
return 0;
}
The program output is
The sum of perfect squares is 14
First element in an array is A[0]. You're returning 0 rather than the value of A[0] when you're calling sum(A,0).
Did you try changing the line to: if (n<=0) return A(0);?

recursive find number in between in C

I want to find the number within a range in an array and must be in a recursive way. The function variables couldn't be modified.
Let's say in the range of 2 and 3
The input is : int a[] = {4, 1, 3, 1, 3, 2};
and the output will be = {3,3,2} , 3 found
Not sure how to code the recursive function in this case. The below I have tried not working.
int within(int a[], int N, int lower, int upper, int result[])
{
if(N == 1 && N <= upper && N>= lower)
return a[0];
return within(&a[1], N-1, lower, upper, result);
}
int main()
{
int a[] = {4, 1, 3, 1, 3, 2};
int result[6] = {0};
int i, nResult;
nResult = within(a, 6, 2, 3, result);
printf("%d data passed the bounds\n", nResult);
for (i = 0; i < nResult; i++){
printf("%d ", result[i]);
}
printf("\n");
return 0;
}
I want to find the number within a range in an array
Let's say in the range of 2 and 3
Normally a for loop or similar would be so much easier here
If it has to be recursive....
// need to have another number - r - number in range
// r starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int r, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[r]= a[0];
r++;
}
if(N==0) {
return r;
} else {
r = within(&a[1], N-1, lower, upper, r, result);
return r;
}
}
the function will give a return value of the number of values found within the range.
The code above is recursive, but so much more complicated and fragile than a simple loop... such as the fragment below
for (i=0;i<N;i++) {
if(a[i] <= upper && a[i]>= lower) {
result[r]= a[i];
r++;
}
}
If it has to be recursive wihtout r...
// need to have another number - result[0] - number in range
// result[0] starts at zero
//
// normally lower case for variable and capitals for things you #define
// N starts at the number of elements of a less one
//
int within(int a[], int N, int lower, int upper, int result[])
{
if(a[0] <= upper && a[0]>= lower) {
result[0]++;
result[result[0]]= a[0];
}
if(N==0) {
return result[0];
} else {
result[0] = within(&a[1], N-1, lower, upper, result);
return result[0];
}
}
now result conatins
{number in range, first number in range, second number in range....}
Something like this. If you want to implement a recursive function, try to do it in the way that the recursive call happens at the end.
#include <stdio.h>
int find_in_range(int* out, int const *in, int length, int from, int to)
{
if (length == 0)
{
return 0;
}
int addon;
if (*in >= from && *in <= to)
{
*out = *in;
++out;
addon = 1;
}
else
{
addon = 0;
}
return find_in_range(out, in + 1, length - 1, from, to) + addon;
}
#define N 6
int main()
{
int in[N] = {4, 1, 3, 1, 3, 2};
int out[N] = {0};
int num_found = find_in_range(out, in, N, 2, 3);
for (int i = 0; i < num_found; ++i)
{
printf("%d ", out[i]);
}
printf("\n");
return 0;
}
You can modify the following code as per your requirements. This is just a proof of concept code:
#include <stdio.h>
#include <stdlib.h>
static int result[4];
static int ctr1 = 0;
static int ctr2 = 0;
void recFind(int* arr, int* key){
if(ctr2 == 8)
return;
if(*arr >= key[0] && *arr <= key[1])
result[ctr1++] = *arr;
arr++;
ctr2++;
recFind(arr, key);
}
int main(){
int arr[] = {1,3,3,6,4,6,7,8};
int key[] = {1,4};
recFind(arr, key);
printf(" { ");
for(int i = 0; i < 4; i++){
printf("%d ", result[i]);
}
printf("}\n");
}
As it follows from the description of the assignment the function should provide two values: the number of elements that satisfy the condition and an array that contains the elements themselves.
It is evident that the array should be allocated dynamically. And it is logically consistent when the function itself returns the number of elements while the pointer to the generated array is passed by reference as an argument.
The recursive function can look the following way
#include <stdio.h>
#include <stdlib.h>
size_t get_range( const int a[], size_t n, int lower, int upper, int **out )
{
size_t m;
if ( n )
{
m = get_range( a, n - 1, lower, upper, out );
if ( lower <= a[n-1] && a[n-1] <= upper )
{
int *tmp = realloc( *out, ( m + 1 ) * sizeof( int ) );
if ( tmp )
{
tmp[m] = a[n-1];
*out = tmp;
++m;
}
}
}
else
{
*out = NULL;
m = 0;
}
return m;
}
int main(void)
{
int a[] = { 1, 2, 3, 4, 5, 4, 3, 2, 1 };
const size_t N = sizeof( a ) / sizeof( *a );
int lower = 2, high = 3;
int *out;
size_t n = get_range( a, N, lower, high, &out );
for ( size_t i = 0; i < n; i++ )
{
printf( "%d ", out[i] );
}
putchar( '\n' );
free( out );
return 0;
}
The program output is
2 3 3 2
Below codes will work for you in recursive way. If you don't want to print the numbers just comment out printf statement inside function printfRange. Hope you can understand the logic :-
int within(int *a, int rngH, int rngL, int length)
{
int len = length;
static int i = 0;
static int found = 0;
if(len <=0 )
{
return i;
}
if (*a == rngH)
{
printf("%d,",*a);
i++;
found = 1;
within(++a,rngH, rngL,--len);
}
else if(*a == rngL && found > 0)
{
printf("%d,",*a);
i++;
within(++a,rngH, rngL,--len);
}
else
{
within(++a,rngH, rngL,--len);
}
return i;
}
int main() {
int a[] = {4, 1, 3, 1, 3, 2};
int total = within(a,3,2,6);
printf("\n");
printf("Total :%d\n",total);
return 0;
}

c programming array element subtraction [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
array a1 = [1, 2, 3, 4, 5, 8];
array a2 = [1, 4, 5];
array a3 = a1 - a2; /* [2, 3, 8] */
array a4 = a2 - a1; /* print -None */
Here array would be the type my program uses to represent a struct which is used as a container. The rest of it is pseudo code, of course I'm not creating the arrays like that nor subtracting.
The simplest solution I can think of involves nested loops. any idea to solve an efficient way to solve this problem?
You want set difference. If both arrays are sorted, and contain no duplicates, you can iterate through both simultaneously:in linear time.
Whenever you encounter an element b in list B greater than the current element a of A, you can be sure that B does not contain a (or it would not be sorted). Then a is in A and not B, so it is in your output. Proceed to the next element of A, and compare it to the first element of B greater than the previous a, which is your current b. If b < a, it is also less than any remaining element of a, so you can advance to the next element of b. If you do encounter a == b, it is not in the set difference, so compare the next elements of both lists. If you reach the end of B first, add all remaining elements of A. When you reach the end of A, stop.
You can sort a list and remove duplicates in O(n log n) time, or faster if you can radix sort.
Sample Code
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
void print_set( const size_t asize, const int a[asize] )
{
const ptrdiff_t n = (ptrdiff_t)asize;
assert(n >= 0);
putchar('{');
if (n > 0) {
printf( "%d", a[0] );
for ( ptrdiff_t i = 1; i < n; ++i )
printf( ", %d", a[i] );
}
putchar('}');
fflush(stdout);
return;
}
size_t setdiff( const size_t asize, const int a[asize],
const size_t bsize, const int b[bsize],
const size_t csize, int c[csize] )
/* Calculates c = a - b, where a, b and c are sets. Returns the number of
* elements in c. The destination array c must be large enough to hold the
* result (asize elements are always enough). All sets must be sorted and
* contain no duplicates (checked at runtime).
*/
{
ptrdiff_t i = 0, j = 0, k = 0;
const ptrdiff_t m = (ptrdiff_t)asize;
const ptrdiff_t n = (ptrdiff_t)bsize;
const ptrdiff_t p = (ptrdiff_t)csize;
assert(m >= 0);
assert(n >= 0);
assert(p >= 0);
while ( i < m ) {
if ( j == n || a[i] < b[j] ) {
assert( k < p );
c[k++] = a[i++];
assert( i == m || a[i] > a[i-1]);
} else if ( a[i] > b[j] ) {
++j;
assert( j == n || b[j] > b[j-1]);
} else {
assert( a[i] == b[j] );
++i;
assert( i == m || a[i] > a[i-1]);
++j;
assert( j == n || b[j] > b[j-1]);
}
}
return (size_t)k;
}
int main(void)
{
static const int a[] = {1, 2, 3, 4, 5, 6};
static const size_t m = sizeof(a)/sizeof(a[0]);
static const int b[] = {1, 4, 5};
static const size_t n = sizeof(b)/sizeof(b[0]);
int c[6] = {0};
static const size_t p = sizeof(c)/sizeof(c[0]);
print_set( m, a );
printf(" - ");
print_set( n, b );
printf(" = ");
const size_t q = setdiff( m, a, n, b, p, c );
print_set( q, c );
printf(".\n");
print_set( n, b );
printf(" - ");
print_set( m, a );
printf(" = ");
const size_t r = setdiff( n, b, m, a, p, c );
print_set( r, c );
printf(".\n");
return EXIT_SUCCESS;
}
Assuming the two arrays are sorted, as in your examples, you should be able to locate common elements optimally using bsearch. I've provided an example, but in the future please make an effort to write your own C code in the future, then I/we might be able to help you better!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int compare(void const *x, void const *y) {
return memcmp(x, y, sizeof (int)); // XXX: This might not be what you expect for negative values!
}
size_t difference(void *dest, size_t dest_size, void const *x, size_t x_size, void const *y, size_t y_size, size_t size, int (*compare)(void const *, void const *)) {
typedef unsigned char item[size];
item const *a = x, *b = y;
item *d = dest;
size_t cursor = 0, d_size = 0;
for (size_t x = 0; x < x_size; x++) {
item *ptr = bsearch(a + x, b + cursor, y_size - cursor, size, compare);
if (ptr) {
cursor = ptr - b;
}
else {
memcpy(d[d_size++], a[x], sizeof (item));
}
}
return d_size;
}
void print(char *name, int array[], size_t array_size) {
printf("%s: %s", name, array_size ? "" : "NONE\n");
for (size_t x = 0; x < array_size; x++, putchar(x < array_size ? ',' : '\n')) {
printf("%d", array[x]);
}
}
int main(void) {
int a[] = { 1, 2, 3, 4, 5, 8 },
b[] = { 1, 4, 5 },
c[sizeof a / sizeof *a],
d[sizeof a / sizeof *a];
size_t c_size = difference(c, sizeof c / sizeof *c,
a, sizeof a / sizeof *a,
b, sizeof b / sizeof *b,
sizeof (int), compare);
size_t d_size = difference(d, sizeof d / sizeof *d,
b, sizeof b / sizeof *b,
a, sizeof a / sizeof *a,
sizeof (int), compare);
print("c", c, c_size);
print("d", d, d_size);
}
First, you will obviously need a find function:
int find(int val, const int* a, int na)
{
int i;
for (i = 0; i < na; ++i)
{
if (val == a[i])
return i;
}
return -1;
}
The diff function become quite trivial, assuming you have an allocated array for the result. r should be able to hold at least na elements.
int diff(int* r, const int* a, int na, const int* b, int nb)
{
// returns the number of elenment in resulting set.
// on output r contains the elements from a that are not found in b
// expects r to provide enough room for na elements
int i, nr;
nr = 0;
for (i = 0; i < na; ++i)
{
if (find(a[i], b, nb) < 0)
{
r[nr++] = a[i];
}
}
return nr;
}
I know that in a sense, this is still a nested loop. But it is much more readable. Plus, you've gained a generic find() function that you can use elsewhere in your code.
I thought the difference of two sets was not as you describe, but defined as A with intersection of A and B removed. i.e. If a value is found several times in A, but only once in B, only one element of A is removed from the result set. For this case, you'd need a remove function.
int remove(int at, int* a, int na)
{
// removes first occurence of val in a.
// returns the number of elements in a after remove op.
if (0 <= at && at < na)
{
memmove(&a[at], &a[at + 1], sizeof(int) * (na - (at + 1)));
return na - 1;
}
return na;
}
The diff when elements are not unique is not much more complex, we'll loop on b.
int difference(int* r, const int* a, int na, const int* b, int nb)
{
// returns elements from a, minus set b.
// handles non-unique cases, so this is the true difference or a-b
// returns the number of elements in resulting set
int nr, found;
memcpy(r, a, na * sizeof(int));
nr = na;
for (i = 0; i < nb; ++i)
{
found = find(b[i], r, nr);
if (found >= 0)
{
nr = remove(found, r, nr);
}
}
return nr;
}
I did not try to compile these, so there might be some typos, but it should be fairly close..
Edit: These algorithms have a complexity of O(N^2), so by sorting a (or b) and using a binary search, you could get them down to 1) O(2NlogN) 2) O(3NlogN), which is not bad, since you'd only need to change the find() function to implement optimization.

palindrome checker algorithm

i'm having problems writing this excercise.
this should evaluate if a given array contains a palindrome sequence of numbers, the program builds correctly but doesn't run (console remains black). where am i wrong on this? thanks for all help!
#include <stdio.h>
#include <stdlib.h>
#define SIZE 15
//i'm using const int as exercise demand for it
//should i declare size as int when giving it to function? also if it's been declared?
//i'm a bit confused about that
int palindrome(const int a[], int p, int size);
int main()
{
int a[SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1, 0};
int p = 1; //i'm not using boolean values, but i think should work anyway, right?
p = palindrome(a, p, SIZE);
if (p)
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");
return 0;
}
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
while (p) {
for (j = 0; j < (SIZE / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]) //i think i might be wrong on this, but don't know where i'm in fault
p = 0;
}
}
return p;
}
p.s.
how can i activate debugger "watches" on Code Blocks to look at others function variables? (i put a stop on main function)
You don't need while (p) { loop. It is possible to have infinite loop here (and you have it!), because if you don't change p, this loop never stops.
You mix size and SIZE in the implementation of palindrome() (mid is half of size, but the whole loop is from 0 to SIZE-1).
Also it is better to move int p = 1; in the beginning of implementation of palindrome() (and to remove int p from list of it's parameters).
Just try this:
int palindrome(const int a[], int p, int size)
{
int mid, j;
mid = size / 2;
for (j = 0; j < (size / 2); j++){
if (a[mid + (j + 1)] != a[mid - (j + 1)]);
p = 0;
break;
}
}
return p;
}
here's an alternative without p where palindrome returns 0 or 1
int palindrome(const int a[], int size)
{
int j , k , ret;
for (j = 0 , k = size - 1 ; j < k; j++ , k--)
{
if (a[j)] != a[k])
{
ret = 0;
break;
}
}
if(j >= k)
ret = 1;
return ret;
}
you can call palindrome in the if statement in main like this :
if(palindrome(a , SIZE))
printf("\nseries is palindrome\n");
else
printf("\nseries isn't palindrome\n");

Resources