Find elements from an array whose sum equals a given number - c

I am try to write a A recursive implementation, but it dont work. Can you help me to find mistake. I need just a recursive solution on C.
void findsum(int arr[],int i, int k){
if (k <= 0 || arr[i] > k) return;
if (arr[i] <= k) {
k -= arr[i];
if (k == 0) {
NSLog(#"Summ %d, %d",arr[i], arr[i]); return;
}
}
if (i == (25)) return;
for (int a=i ;a<25; a ++ ) {
findsum(arr, a, k);
}
}
int main()
{
int set[] = {18897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
int sum = 100000000;
int n = sizeof(set)/sizeof(set[0]);
for (int i = 0; i < n; i++) {
findsum(set, i, sum);
}
}

You code not stop because every time you assign i=0 by loop
for (i = 0 ;i<26; i ++ ) {
findsum(arr, i, k);
}
In findsum function.
So as per my suggestion you can make some changes as like
first in main
int main()
{
int set[] = {18897109, 12828837, 9461105, 6371773, 5965343, 5946800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279833, 3095313, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411};
int sum = 100000000,i;
int n = sizeof(set)/sizeof(set[0]);
findsum(set, n, sum);
}
And second in findsum like
void findsum(int arr[],int i, int k)
{
if (k <= 0 || arr[i] > k) return;
if (arr[i] <= k)
{
k -= arr[i];
if (k == 0) {
NSLog(#"Summ %d, %d",arr[i], arr[i]); return;
}
}
if (i == 25) return;
findsum(arr, i, k);
}

Related

How the counting is conducted in this function?

See the function search below, it returns count but I don't see where this variable count acts/works (the function is found in a library , click here to download the source code, you will find kmp.c in \source\algos):
#include "include/define.h"
#include "include/main.h"
void preKmp(unsigned char *x, int m, int kmpNext[]) {
int i, j;
i = 0;
j = kmpNext[0] = -1;
while (i < m) {
while (j > -1 && x[i] != x[j])
j = kmpNext[j];
i++;
j++;
if (i<m && x[i] == x[j])
kmpNext[i] = kmpNext[j];
else
kmpNext[i] = j;
}
}
int search(unsigned char *x, int m, unsigned char *y, int n) {
int i, j, kmpNext[XSIZE], count;
/* Preprocessing */
BEGIN_PREPROCESSING
preKmp(x, m, kmpNext);
END_PREPROCESSING
/* Searching */
BEGIN_SEARCHING
count = 0;
i = j = 0;
while (j < n) {
while (i > -1 && x[i] != y[j])
i = kmpNext[i];
i++;
j++;
if (i >= m) {
OUTPUT(j - i);
i = kmpNext[i];
}
}
END_SEARCHING
return count;
}
Can any one explain how it works?
The OUTPUT macro that is defined in ./source/algos/include/define.h looks like this:
#define OUTPUT(j) count++
And in search you have
if (i >= m) {
OUTPUT(j - i); // <- here
i = kmpNext[i];
}
which explains how count is updated.

Recursive function to verify Matrix is Symmetric in C

I am just working on a recursive function to verify if a matrix is symmetric or not. The matrix must be square and I am considering max n = 20. I could develop the function:
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (!((n == i) || (n == j))) {
if (m[i][j] != m[j][i]) {
return 0;
} else {
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
}
}
return 1;
}
Below is a code to run:
#include <stdio.h>
#include <stdlib.h>
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (!((n == i) || (n == j))) {
if (m[i][j] != m[j][i]) {
return 0;
} else {
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
}
}
return 1;
}
int main() {
int n, r, c, m[20][20], t[20][20], flag, i, j;
i = j = 0;
printf("Enter matrix order >> ");
scanf("%d", &n);
printf("\nEnter the elements \n");
for (r = 0; r < n; r++) {
for (c = 0; c < n; c++) {
printf("m[%d][%d]: ", r + 1, c + 1);
scanf("%d", &m[r][c]);
}
}
for (r = 0; r < n; r++)
for (c = 0; c < n; c++)
t[c][r] = m[r][c];
flag = verifySymmetric(m, i, j, n);
if (flag == 1)
printf("Matrix is symmetric ");
if (flag == 0)
printf("Matrix is not symmetric ");
return 0;
}
My main concern is about the line
return (verifySymmetric(m, i + 1, j, n) && verifySymmetric(m, i, j + 1, n));
The program seem to work but I noticed that many m[row][column] is printed when I run the code. Something like this
Enter the elements
m[1][1]: m[1][2]: m[1][3]: m[1][4]: m[1][5]: m[1][6]: m[1][7]: m[1][8]: m[1][9]: m[1][10]: m[1]
[11]: m[1][12]: m[1][13]: m[1][14]: m[1][15]: m[1][16]: m[1][17]: m[1][18]: m[1][19]: m[1][20]:
m[1][21]: m[1][22]: m[1][23]: m[1][24]: m[1][25]: m[1][26]: m[1][27]: m[1][28]: m[1][29]: m[1]
[30]: m[1][31]: m[1][32]: m[1][33]: m[1][34]: m[1][35]: m[1][36]: m[1][37]: m[1][38]: m[1][39]:
m[1][40]: m[1][41]: m[1][42]: m[1][43]: m[1][44]: m[2][1]: m[2][2]: m[2][3]: m[2][4]: m[2][5]:
m[2][6]: m[2][7]: m[2][8]: m[2][9]: m[2][10]: m[2][11]: m[2][12]: m[2][13]: m[2][14]: m[2][15]:
m[2][16]: m[2][17]: m[2][18]: m[2][19]: m[2][20]: m[2][21]: m[2][22]: m[2][23]: m[2][24]:
What would be wrong with the function?
What would be another approach?
Edit
This is not a good approach, using recursion for a function like this, but I was curious about it and couldn't find an example in the internet. It is basically for learning purposes.
I am using Visual Studio Code and the strange behavior described above is when I click to Run Code two times. Running once, it runs as I expected, printing Enter matrix order >> , but once I click it for the second time without entering the matrix order, the misbehavior happens.
The code seems to work but it is very inefficient as the recursive approach will cause many redundant comparisons. The time complexity is O(n4) instead of O(n2)
You reason you get this misleading output is you prompt for each matrix value to stdout, but the input is read from a file and not echoed to stdout.
Here is a simpler non-recursive approach:
#include <stdio.h>
int verifySymmetric(int m[20][20], int n) {
for (int r = 0; r < n; r++) {
for (int c = 0; c < r; c++) {
if (m[r][c] != m[c][r])
return 0;
}
}
return 1;
}
int main() {
int n, m[20][20];
printf("Enter matrix order >> ");
if (scanf("%d", &n) != 1) {
printf("missing input\n");
return 1;
}
if (n < 1 || n > 20) {
printf("invalid dimension %d\n", n);
return 1;
}
printf("\nEnter the elements\n");
for (int r = 0; r < n; r++) {
for (int c = 0; c < n; c++)
if (scanf("%d", &m[r][c]) != 1) {
printf("missing input\n");
return 1;
}
}
}
if (verifySymmetric(m, n)) {
printf("Matrix is symmetric\n");
else
printf("Matrix is not symmetric\n");
return 0;
}
If for some reason the implementation is required to be recursive, here is a modified version without redundant comparisons:
int verifySymmetric(int m[20][20], int i, int j, int n) {
if (j == n) {
return 1;
} else
if (i < j) {
return (m[i][j] == m[j][i]) && verifySymmetric(m, i + 1, j, n);
} else {
return verifySymmetric(m, 0, j + 1, n);
}
}

Why isn't the code coming out of recursion?

The problem is to find the number of times a word occurs in a given N x N matrix of alphabets. We can move from any cell to other adjacent cell. The first line has one integer N and then a N x N matrix. Next line has M (size of the word) and then a string to be found in the matrix.
Input:
4
ABCD
ABCD
ABCD
ABCD
2
BC
Expected output:
10
I have written the following code for the same and used recursion for solving the problem. The function adj checks if the character is adjacent in the matrix with the previous character using their indexes. The function check increases the count whenever the string is completed. The 2-d array keeps a check on the visited and unvisited elements.
I am getting the output as
OUPUT
1
EDIT 1: This output is just because of the debugging print statement, so the if statement is being visited only once. It does not mean that the count variable is 1 after many recursion calls.
EDIT 2: There shouldn't be & in the scanf statement for word. But still the output is not the desired one.
EDIT 3:
Another input
7
SHELDON
HSTYUPQ
EHGXBAJ
LMNNQQI
DTYUIOP
OZXCVBN
NQWERTY
7
SHELDON
Expected output:
5
My output - 1
EDIT 4(Solved!): So the problem was in writing the no. of columns as 500 for the grid matrix, changing it to 5 did the job! Thanks to #gsamaras
Code
#include <stdio.h>
int vis[500][500], count;
int adj(int a, int b, int c, int d) {
if((c == a - 1) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b)) {
return 1;
}
else if((c == a) && (d == b - 1)) {
return 1;
}
else if((c == a - 1) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b)) {
return 1;
}
else if((c == a + 1) && (d == b + 1)) {
return 1;
}
else if((c == a) && (d == b + 1)) {
return 1;
}
else if((c == a + 1) && (d == b - 1)) {
return 1;
}
else {
return 0;
}
}
void check(char grid[][500],int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("%d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < n; q++) {
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char grid[n][n+1];
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", &word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
return 0;
}
Change this:
void check(char grid[][500], ......
to this:
void check(char grid[][5], ....... // that should be equal to N + 1 (5 in your case)
since your grid is of size N x N + 1. With the 500 as the dimension, you distorted the grid, and when trying to search into it recursively, you wouldn't traverse the grid that you would expect to traverse..
As you see this is not flexible, since N can vary. You cannot declare grid as global, since its dimensions are not fixed. Dynamic memory allocation should be used instead.
Change this:
scanf("%s", &word);
to this:
scanf("%s", word);
since word is an array of characters.
Complete example with Dynamic Memory Allocation:
#include <stdio.h>
#include <stdlib.h>
int vis[500][500], count;
char **get(int N, int M) { /* Allocate the array */
int i;
char **p;
p = malloc(N*sizeof(char *));
for(i = 0 ; i < N ; i++)
p[i] = malloc( M*sizeof(char) );
return p;
}
void free2Darray(char** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int adj(int a, int b, int c, int d) {
// Same as in your question
}
void check(char** grid, int i, int j, int id, char word[], int n, int m) {
if(id == m) {
count++;
printf("count = %d\n", count); // just to debug
}
else {
for(int p = 0; p < n; p++) {
for(int q = 0;q < 499; q++) {
//printf("p = %d, q = %d, id = %d, grid[p][q] = %c, word[id] = %c\n", p, q, id, grid[p][q], word[id]);
if((grid[p][q] == word[id]) && (adj(i, j, p, q)) && (vis[p][q] != 1)) {
vis[p][q] = 1;
check(grid, p, q, id + 1, word, n, m);
vis[p][q] = 0;
}
}
}
}
}
int main() {
int n, m, id = 0;
char blank;
scanf("%d", &n);
scanf("%c", &blank);
char** grid = get(n, n + 1);
for(int i = 0; i < n; i++) {
scanf("%s", grid[i]);
grid[i][n] = '\0';
}
scanf("%d", &m);
char word[m+1];
scanf("%s", word);
for(int i = 0; i < n; i++) {
for(int j = 0;j < n; j++) {
//printf("i = %d, j = %d, id = %d\n", i, j, id);
if(grid[i][j] == word[id]) {
vis[i][j] = 1;
check(grid, i, j, id + 1, word, n, m);
vis[i][j] = 0;
}
}
}
printf("%d\n", count);
free2Darray(grid, n);
return 0;
}
Output (for your 1st input):
count = 1
count = 2
count = 3
count = 4
count = 5
count = 6
count = 7
count = 8
count = 9
count = 10
10
PS: Not a problem, just a suggestion about readability: count is initialized to 0, because it's a global variable, but it's always best to explicitly initialize your variables, when it matters.

Why this reverse function can not work in the for loop?

#include <stdio.h>
#include <math.h>
int prime (long n);
long reverse(long n);
int main(void)
{
long n;
long i, j;
puts("Enter n dight number, and we will help you find symmetrical prime number");
scanf("%ld", &n);
for (i = 11; i < (pow(10, n) - 1); i+= 2)
{
if (prime(i))
{
j = reverse(i);
if (i == j)
{
printf("%ld\n", i);
}
}
}
}
int prime (long n) //estimate whether the number n is primer number
{
int status = 0;
int j;
//1 is prime, 0 is not
if (n % 2 == 0 || n == 3)
{
if (n == 2)
status = 1;
if (n == 3)
status = 1;
else
{
n++;
status = 0;
}
}
else
{
j = 3;
while (j <= sqrt(n))
{
if (n % j == 0)
{
status = 0;
break;
}
else
status = 1;
j+= 2;
}
}
return status;
}
long reverse(long n) //reverse a number
{
int i, j, x;
long k, sum;
int digit = 0;
int ar[1000];
while (n > 0)
{
k = n;
n = n / 10;
x = (k - n*10);
digit++;
ar[digit] = x;
}
for (i = 1,j = digit - 1; i <= digit; i++, j--)
{
sum += ar[i] * pow(10, j)
}
return sum;
}
I build a reverse function in order to reverse numbers, for example, 214, to 412.
This function works fine in individual number, for instance, I type reverse(214), it return 412, which is good. But when I combine reverse() function with for loop, this function can not work... it produces some strange number...
so How can I fix this problem?
The reverse function is extremely complicated. The better way to go about it would be:
long reverse (long n)
{
long result = 0;
while (n != 0)
{
result *= 10;
result += n % 10;
n /= 10;
}
return result;
}
I think the problem in your code is that in the following segment
digit++;
ar[digit] = x;
you first increment the position then assign to it, thus leaving ar[0] unintialized.
How can I fix this problem?
You need to initialize sum
long k, sum = 0;
^
See the code from #Armen Tsirunyan for a simpler approach.

intersection and union of n-arrays in C

I have those functions which are making intersection/union but just of two arrays.
I need too improve them to work with n-arrays: arr = {{1,2,3},{1,5,6},...,{1,9}}.
The arrays are sorted , and their elements are unique among them.
Example (intersection):
Input: {{1,2,3,4},{2,5,4},{4,7,8}}
Output: {4}
arr1[],arr2 - arrays
m,n - length of the arrays
Intersection function:
int printIntersection(int arr1[], int arr2[], int m, int n)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
i++;
else if(arr2[j] < arr1[i])
j++;
else /* if arr1[i] == arr2[j] */
{
printf(" %d ", arr2[j++]);
i++;
}
}
}
and union function:
int printUnion(int arr1[], int arr2[], int m, int n)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
printf(" %d ", arr1[i++]);
else if(arr2[j] < arr1[i])
printf(" %d ", arr2[j++]);
else
{
printf(" %d ", arr2[j++]);
i++;
}
}
while(i < m)
printf(" %d ", arr1[i++]);
while(j < n)
printf(" %d ", arr2[j++]);
}
union(a, b, c) = union(union(a, b), c), and the same goes for intersection(). I.e. you can decompose the union or intersection of n sets into n unions or intersections of 2 sets (as NuclearGhost points out in a comment on the question). What you need to do is change your current functions so that they build up a resulting set, instead of immediately printing the result. You can then make a separate function that prints a set.
For efficiency, you want to take the union or intersection of sets that are roughly of equal size. So a divide-and-conquer approach should work alright, assuming that all input sets are likely to be of roughly equal size.
void intersection(int arr1[], int arr2[], int m, int n, int *out)
{
int i = 0, j = 0;
while(i < m && j < n)
{
if(arr1[i] < arr2[j])
i++;
else if(arr2[j] < arr1[i])
j++;
else /* if arr1[i] == arr2[j] */
{
*out++ = arr2[j++];
i++;
}
}
}
void multi_intersection(int n, int **arrays, int *lengths, int *out) {
if (n == 2) {
intersection(arrays[0], arrays[1], lengths[0], lengths[1], out);
} else if (n == 1) {
memcpy(out, arrays[0], lengths[0] * sizeof (int));
} else {
/* Allocate buffers large enough */
int *buf[2];
int len[2] = { INT_MAX, INT_MAX };
int i;
for (i = 0; i < n; ++i) {
int which = i < n / 2;
if (lengths[i] < len[which]) len[which] = lengths[i];
}
buf[0] = malloc(len[0] * sizeof (int));
buf[1] = malloc(len[1] * sizeof (int));
/* Recurse to process child subproblems */
multi_intersection(n / 2, arrays, lengths, buf[0]);
multi_intersection(n - n / 2, arrays + n / 2, lengths + n / 2, buf[1]);
/* Combine child solutions */
intersection(buf[0], buf[1], len, out);
free(buf[0]);
free(buf[1]);
}
Similar code works for multi_union(), except that the buffer lengths need to be calculated differently: the result of a union could be as large as the sum of the sizes of the inputs, rather than the minimum size of the inputs. It could probably be rewritten to do less buffer allocation. Also the recursion could be rewritten to use iteration, the same way mergesort can be written to use iteration, but the current recursive approach uses only O(log n) additional stack space anyway.
presume the max value in arrays is less than K. N is the number of arrays
int Result[K] = {0};
intersection function
//input array1
int index = 0;
for(; index < arrary1len;index++)
{
Result[array1]++;
}
.....
for(index = 0; index < K; index++)
{
if(Result[index] == N)
printf("%d",index);
}

Resources