Count occurences of a subarray in a bigger array using recursion - c

I have to write a recursive function that counts how many times a short array s2 is present in a bigger array s1 without overlapping. I'm allowed to use more than one function that can help me but they have to be all recursive function. For example:
#define n 10
#define p 2
s1[n]={0,2,3,23,54,1,8,23,54,1}
s2[p]={23,54}
OUTPUT: 2 (we see s2 two times in s1)
I thought about writing a recursive function that tells me if there is at least one occurence then use this function in another recursive function that counts the number of occurences. So this is what I wrote:
//Initially pos1=0 and pos2=0
int find(int *s1,int *s2,int pos1,int pos2){
if(n-pos1<p-pos2)
return 0;
if(*(s1+pos1)==*(s2+pos2)){
if(pos2==p-1)
return pos1;
else{
if(find(s1,s2,pos1+1,pos2+1))
return pos1;
}
}
return find(s1,s2,pos1+1,0);
}
Then I wrote the second recursive function that is supposed to count the number of occurences:
// Initially occ(s1,s2,0);
int occ(int *s1,int *s2,int memo){
if(memo==n){ //end of s1
return 0;
}
else{
if(find(s1+memo,s2,memo,0))
return 1+occ(s1+memo,s2,memo+p);
}
}
The idea behind it is to verify if there is at least one occurence if there is an occurence then count it and redo the verification for the remaining part of s1 until the end.
The problem is that the code of the second function doesn't work at all and I can't find a way to fix it.
So how can I write a second recursive function that COUNTS the number of occurences using the function find() written above?

From the OP's comment
It works if s1[n]={0,0,0,3,4,0,0,0,3,4,0,0,0,3,4,0,0,0,3,4}; and s2[p]={3,4}. Indeed the output is 4. But if s2[p]={0,0} the output is 0 which is not correct.
This is because, when s2={0,0} the find() function returns pos1 = 0 as the subset is present at the very beginning and thus in occ() function if(find(s1+memo,s2,memo,0)) evaluates to be false and terminates the function without returning any value and this invokes undefined behavior
This can be avoided by returning any number other than 0 but it must not be the any valid position value in the array s1.
Since position cannot be negative number, I've chosen -1
See the following code to know how to avoid it :
#include <stdio.h>
#define n 10
#define p 2
int s1[n]={0,2,3,23,54,1,8,23,54,1};
int s2[p]={23,54};
//find function
int find(int* s1,int* s2,int pos) //only used `pos` instead of `pos1`, removed `pos2`
{
if(pos > n-2)
{
return -1; //returns `-1` upon reaching the end of the code
}
if(*(s1+pos) == *(s2+0)) //check at `s1+pos`
{
if(*(s1+(pos+1)) == *(s2+1)) //check next element `s1+pos+1`
{
return pos; //if both true return `pos`
}
else
{
return find(s1,s2,pos+1); //else recursively find in the rest of the array
}
}
return find(s1,s2,pos+1); // recursively find in the rest of the array
}
//occurence function
int occ(int *s1, int *s2,int memo)
{
if(memo == -1) //if end of the array, end adding occurrences by returning 0
{
return 0;
}
else
{
memo = find(s1, s2, memo); //scan position into memo
if(memo != -1) //if not end of the array i.e, `-1` add to occurrence
{
return 1+occ(s1,s2,memo+2);
}
else
{
return 0; //else return 0 and recursion would end in next call as memo is -1
}
}
}
//main function
int main(void)
{
printf("%d",occ(s1,s2,0)); //just to see the output
}
output :
2 //true as {23,54} occur two times
when input is : (compile time)
#define n 20
#define p 2
s1[n]={0,0,0,3,4,0,0,0,3,4,0,0,0,3,4,0,0,0,3,4};
s2[p]={0,0};
output :
4 //true as {0,0} occurs at 0,5,10,16

Related

Finding indexes where substring is present

So right now my code checks if the sub string is present in the code and returns true or false, I would like to find where these substrings are located in the total string. how can you implement that.
#include <stdio.h>
#include <stdbool.h>
bool checksub(const char *strng,const char *subs){
if (*strng=='\0' && *subs!='\0'){
return false;
}
if (*subs=='\0'){
return true;}
if (*strng==*subs){
return checksub(strng+1,subs+1);
}
return false;
}
bool lsub(char *strng,char *subs){
if (*strng=='\0'){
return false;
}
if (*strng==*subs){
if (checksub(strng,subs)){
return 1;
}
}
return lsub(strng+1,subs);
}
int main(){
printf("%d\n",checksub("ababuu","ab"));
printf("%d\n",checksub("the bed bug bites","bit"));
return 0;
}
First you should get rid of recursion since it's often slow and dangerous, for nothing gained.
A (naive) version of strstr that returns an index rather than a pointer might look like this:
int strstr_index (const char* original, const char* sub)
{
int index = -1;
for(const char* str=original; *str!='\0' && index==-1; str++)
{
for(size_t i=0; str[i]==sub[i] && str[i]!='\0'; i++)
{
if(sub[i+1] == '\0')
{
index = (int)(str - original);
break;
}
}
}
return index;
}
This returns -1 if not found, otherwise an index.
It iterates across the string one character at a time.
When a character match with the sub string is found, it starts executing the inner loop as well.
If the inner loop continues to find matches all the way to the end of the sub string, then we found a match.
The index can be obtained by pointer arithmetic: the start address of the found sub string minus the start of the string. The result of that subtraction is strictly speaking a special integer type called ptrdiff_t, but I used int to simplify the example.

what fuction fits for unbalanced parantheses

Input
s = "()())()"
Output:
1
Here in the below code I should fill code to count unbalanced perantheses
Tried to start with counting first but gave me wrong output
#include <stdio.h>
int invalid_parentheses_count(char parentheses[])
{
// write your code here
int i,count=0;
for (i=0;i<=strlen(parentheses);i++)
{
if(parentheses[i]=='('|| parentheses[i]==')')
count = count+parentheses[i];
}
printf("%d",count);
return 0;
}
For example, given the string "()())()", you should return 1. Given the string ")(", you should return 2, since we must remove all of them.

Function is returning 1 instead of a value?

I am writing a Queue data structure and I am not able to retain the value of the integer in the array once the value is returned in the stack. The pop function is doing exactly what it needs to do but why doesn't main get that information? What am I missing? malloc?
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
int QUE[20];
const int EMPTY = -1;
int position = -1;
int retrieve = 0;
//push, append to front of array
bool push(int num) {
if (position >= 20) return false;
position += 1;
QUE[position] = num;
return true;
}
//pop from top of array
bool pop() {
if(QUE[retrieve] == 0) return false;
int hold = QUE[retrieve];
printf("%d",hold);
retrieve ++;
return hold;
}
// PEEK
// First in first out
int main() {
push(12);
push(90);
push(22);
int t;
//why does pop equal 1
while ((t = pop()) != 0) {
printf("t = %d\n",t);
}
}
You're trying to pass two different kinds of information – a boolean state 'the pop succeeded' and an integer value popped from the queue – within the same value. That's bad; and the mismatch led you to declaring the return type as bool, which causes the resulting value of t being either zero or one (as a conversion of false or true, respectively, to the int type).
Try to split the action into testing and fetching phase, like:
bool anyItemInQueue()
{
return _add_appropriate_condition_here_;
}
int main()
{
....
while( anyItemInQueue() )
{
int t = pop();
.... // use t here
}
}
or pass another variable to receive another value:
bool pop(int *result)
{
if( anyItemInQueue() )
{
*result = QUE[retrieve];
.... // some housekeeping here
return true; // success status
}
return false; // failure status
}
int main()
{
....
int t;
while( pop( & t ) ) // point at t to receive the popped value
{
.... // use t here
}
}
It is because any non zero value is being converted to bool true and then to integer. The integer value of the bool true is 1
Your code has undefined behavior.
Let's consider for example the function push
//push, append to front of array
bool push(int num) {
if (position >= 20) return false;
position += 1;
QUE[position] = num;
return true;
}
and let's also assume for simplicity that the array QUE has only one element that is it is declared like
int QUE[1];
In this case the queue can only contain one pushed value due to the capacity of the array.
So after a first call of push like
push( 0 );
you will have that position is equal to 0 and the queue contains the value 0.
If to call the function a second time like for example
push( 1 );
the condition within the function
if (position >= 1) return false;
will not evaluate to true because the current value of position is 0. As a result the function will try to write the value 1 into the invalid location of the array QUE[1].
The array contains only one element but the function allows to write one more element.
Now let's consider the function pop
bool pop() {
if(QUE[retrieve] == 0) return false;
int hold = QUE[retrieve];
printf("%d",hold);
retrieve ++;
return hold;
}
and the same queue that already contains only one element equal to 0 (See the previous call push( 0 )).
As the condition of the if statement
if(QUE[retrieve] == 0) return false;
evaluates to true (the queue indeed contains the value 0 pushed on the queue early) then the function will return false as if the queue is empty though it is not empty.
So and this function is invalid.
Moreover in the loop in main
while ((t = pop()) != 0) {
printf("t = %d\n",t);
}
it seems you are trying to output values stored in the queue. However the function does not return such values. Due to the return type bool that is a typedef for the C standard type _Bool any returned value is converted either to 0 or 1.
So the program is in whole wrong.

Function looping when zero is entered

I have a user_get_movement_index function that prompts user to enter a position 0 to 8 as part of a tic-tac-toe game.
This movement index is passed to is_position_empty where it determines if the movement index is invalid or the movement index is already taken, both shows an error message and returns false to trigger a recursion of user_get_movement_index.
Functions loop correctly when the same number is entered twice, and behave as expected when any other number is entered but 0.
The problem is when 0 is entered its causes a loop of the error message of invalid position.
I don't understand how it can be looping from within is_position_empty.
How is it not prompting user for input on each loop?
Why is 0 causing this loop?
Is it because we are comparing 0 < 0 in is_position_empty?
I'm new to C and stack overflow so please forgive my formatting, understanding and terrible code.
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
char my_get_char() {
//1. We create the variable to be returned
char res = ' ';
//2. We create an extra variable to consume any other characters entered until a return is pressed
boolean line_consumed = False;
char dummy_char = ' ';
//3. We consume the first char entered, i.e., the one we are interested at
res = getchar();
//4. While still there are remaining characters
while (line_consumed == False) {
//4.1. We consume the next character
dummy_char = getchar();
//4.2. If the new character is the end of line one, we can ensure we have consumed the entire line.
if (dummy_char == '\n')
line_consumed = True;
}
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
boolean is_position_empty(game* g, int pos) {
//1. We create the variable to be returned
boolean res = False;
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3;
int column = pos%3;
if (pos<0 || pos>8){
printf("\t Invalid Position. Try again!\n\n");
return res;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O'){
printf("\t This postion is already busy. Try Again!\n\n");
return res;
}
else{
res=True;
return res;
}
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g) {
//2. We create a boolean variable to control that we have received a valid movement index.
boolean validMove=False;
//3. We create a char variable to control the index we are receiving by keyboard.
char indexChar;
int indexInt;
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexChar=my_get_char();
indexInt=indexChar-'0';
//We call to is_position_empty to check that the index is a valid one.
validMove=is_position_empty(g, indexInt);
if (validMove==True)
return indexInt;
else
return user_get_movement_index(g);
}
Working Correctly
Working Correctly
Looping
I have boolean defined as the following:
enum Bool { False, True };
typedef enum Bool boolean;
When I initialise all elements of the matrix as 'a', the problem still persists.
When a valid movement is entered, process_movement function is called and it initialises the corresponding element of board to either an 'X' or 'O'.
char mark;
if (g->status==1)
mark='X';
else
mark='O';
int row = pos/3;
int column = pos%3;
g->board[row][column]=mark;
By adding an extra printf within is_position empty, I can tell that the whole function is looping, but it seems to not be exiting is_position_empty as the printf from the function it returns to user_get_movement is not being printed. How is this possible? There is only a loop in user_get_movement and none in is_position_empty, and only loops for 0?
the following proposed code:
is missing the main() function
is missing the function to determine if there was a winner and whom won
is missing the definition of game
does not have any unexpected looping
avoids the problem caused by having a 'recursive' function
and now the proposed code:
#include <stdio.h> // getchar()
#include <stdbool.h> // bool, true, false
#include <ctype.h> // isdigit()
// prototypes
int my_get_char( void );
bool is_position_empty(game* g, int pos);
int user_get_movement_index(game* g);
//--------------------------------------------------
// 05. FUNCTION my_getchar (IMPLEMENTED)
//--------------------------------------------------
int my_get_char()
{
//1. We create the variable to be returned
//3. We consume the first char entered, i.e., the one we are interested at
int res = getchar();
//4. While still there are remaining characters
while ( '\n' != getchar() );
//5. We return res
return res;
}
//------------------------------------
// 06. FUNCTION is_position_empty
//------------------------------------
bool is_position_empty(game* g, int pos)
{
//2. We check if the index is a valid one and if the board is empty at that index.
//If it is valid and free, we return True.
//Otherwise, we return False and write a warning message.
int row= pos/3; = 0
int column = pos%3; = 0
if (pos<0 || pos>8)
{
printf("\t Invalid Position. Try again!\n\n");
return false;
}
else if (g->board[row][column]=='X' || g->board[row][column]=='O')
{
printf("\t This postion is already busy. Try Again!\n\n");
return false;
}
return true;
}
//---------------------------------------
// 07. FUNCTION user_get_movement_index
//---------------------------------------
int user_get_movement_index(game* g)
{
//3. We create a char variable to control the index we are receiving by keyboard.
int indexInt;
do
{
//We print a message asking for a new movement.
printf(" Enter a position 0 to 8: ");
//We call to my_get_char to get the index and we convert it to an integer.
indexInt = my_get_char();
if( isdigit( indexInt ) )
{
indexInt -= '0';
}
else
{
printf( "entry was not in the inclusive range: 0...8\n" );
continue;
}
//We call to is_position_empty to check that the index is a valid one.
} while( !is_position_empty(g, indexInt) );
return indexInt;
}

Function that searches for difference between members of an array

I need to write a function that will return true if it has found a difference between members of an array.
My code is:
int func1(int *str)
{
int i;
for(i=0;i<*(str+i);i++) {
if(*(str+i) == *(str+i+1))
{
return 1;
}
}
return 0;
}
I have to implement it with pointers.
The code above does not work(logically).
Can anybody help?
UPDATE:
I have changed my code to the following:
int func1(int *str)
{
int i,temp=0;
for(i=0;i<10-1;i++) {
if(*(str+i) == *(str+i+1))
{
temp++;
if( temp == 10 )
{
return 1;
}
}
}
return 0;
}
What is the problem with the new code?
This looks like homework to me, so I don't want to spoil the fun but one thing about C I'd like to mention: having a pointer to some array doesn't tell you anything about the size of the array. So your function will need to take a pointer and a second size_t argument (or maybe a pointer to the last element of the array).
Your function only takes in a single array pointer, that seems like one too few for a comparison.
You must add an argument that specifies the lengths of the arrays, or implement some kind of "policy" that e.g. terminates the arrays using a specific value.
You should also look into using the standard memcmp() function.
I don't understand the question (It's unclear what you're trying to achieve)...
As others have already said, there's no boundary checking on your array, which is wrong...
Here's some other feedback on your code:
// func1 - consider giving functions a meaningful name, it helps people to
// understand what the function is supposed to be doing....
// In this instance, it might have been helpful to identify what the expected
// return values / inputs of the function are...
int func1(int *str)
{
int i;
// Start a counter at 0, loop (adding 1) while
// the current value of the counter is less than, the value held in the
// array so, {1,2,3,4,0,7} Would terminate on the 0
// This: {1,20,7,14,0,7} Would also terminate on the 0
// This seems wrong, but again, it's unclear what you're trying to do here.
for(i=0;i<*(str+i);i++) {
// If the current element of the array
// is the same as the next element of the array
if(*(str+i) == *(str+i+1))
{
// return 1 - two numbers next to each other in the
// array are the same?
return 1;
}
}
// Either: The array contained a digit less than the counter,
// Or: It didn't contain two numbers that were the same next to each other.
// This seems a bit wrong?!?
return 0;
}
Your question could be improved (to get a more useful answer), if you showed what inputs you were expecting to return what return values.
Based on this 'I will need to write a function that will return true if its found diffrence between members of array.'
In pseudo code, it seems like you would want:
// Loop, checking we don't overflow. No point checking the last element as
// there's nothing after it to check...
for (count = 0 to arraysize -1) {
// If the current element != the next element, we've found a difference?!?
if(arrayElement[count] != arrayElement[count+1) {
return true
}
}
return false
UPDATE:
In your new code...
// You're still assuming the size of 'str'
int func1(int *str)
{
int i,temp=0;
// Loop while i < 9, i.e. 9 times.
for(i=0;i<10-1;i++) {
if(*(str+i) == *(str+i+1))
{
temp++;
// Temp can never == 10, you're only going round the loop 9 times...
// Maybe it should be (temp == 10-1), but I don't know where the
// 10 comes from...
if( temp == 10 )
{
return 1;
}
}
}
return 0;
}
This:
if(*(str+i) == *(str+i+1))
{
temp++;
// Temp can never == 10, you're only going round the loop 9 times...
if( temp == 10 )
{
return 1;
}
}
Could be:
// return 0 (FALSE) on first difference
if(*(str+i) != *(str+i+1))
{
return 0;
}
If you changed the return 0 at the end of your function to return 1

Resources