Function that searches for difference between members of an array - c

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

Related

How to compare String to list of items in c

I saw another post about similar code but they only compared the string to one other string was wondering if this works / if there's a simple more beginner-friendly way I should learn. Thank you
#include <cs50.h>
#include <stdio.h>
int main(void)
{
string user_imput = get_string("Fruit or Vegetable?, ");
if (strcmp(user_imput, "apple"|| "blueberries" || "cherries" || "bananas" ||"grapes" || "oranges" || "watermelon" ||"lemons" == 0));
{
printf("Fuit!, %s\n", user_imput);
}
else if (strcmp(user_imput, "potatoes" || "tomatoe" || "onions" || "carrot" || "bellpepper" || "lettuce" || "cucumbers" || "broccoli" == 0));
{
printf("Vegtable! %s\n", user_imput);
}
else
{
printf("NA");
}
}```
An easy way to do this is to create a function which searches through an array containing your strings. You then loop through comparing each one individually. If found, we return a truthy value right away. If the loop runs its course and finds nothing, we return a falsy value afterwards.
int is_fruit(string food) {
static const string fruits[] = {
"apple", "blueberries", "cherries" /* ... */
};
for (size_t i = 0; i < (sizeof fruits / sizeof fruits[0]); i++)
if (strcmp(fruits[i], food) == 0)
return 1;
return 0;
}
Then your if ... else looks something like:
if (is_fruit(user_input)) {
/* ... */
} else if (is_vegetable(user_input)) {
/* ... */
} else {
/* ... */
}
A good exercise would be to complete the function above (fill out the array), and write a similar one for vegetables. An even better exercise would be to wring a more generic function that takes a string and any array of strings, and deciding if the array contains the string. Its function prototype would look like this:
int string_array_contains(const string array[], size_t length, const string s);
It would work very similarly to the function above, except you would have to pass in the length of the array, since sizeof cannot be used to determine the length of the array argument.
If functions and arrays are too advanced for you at the moment, then simply know that you must compare each string individually using strcmp. Writing this by hand leads to very long, hard to maintain code:
if (strcmp(user_input, "apple") == 0 || strcmp(user_input, "blueberries") == 0 /* ... */) {
/* ... */
}

If I can't define a variable inside an if-condition, how can I reduce searching through my array multiple times in this code?

I have a function who's body looks a lot like this:
if (contains(array, element1) > -1){
// do something
} else if (contains(array, element2) > -1) {
// do something
} else if (contains(array, element3) > -1) {
// do someting
}...
The function contains will loop through my array and check to see if it contains an element that I pass to it and return either its position if it exists, or -1 if it doesn't.
In my // do something portion, I need the position of this element in the array. There are a couple of different ways I can do this:
I can call my contains() function once more to get the position.
I can define several variables that are defined as the return of the contain function, and then check them in my if-else block. So something like:
int element1Loc = contains(array, element1);
int element2Loc = contains(array, element2);
int element3Loc = contains(array, element3);
if (element1Loc > -1){
// do something
} else if (element2Loc > -1) {
// do something
} else if (element3Loc > -1) {
// do someting
}...
I can perhaps modify contain to return an int array[2], with array[0] equal to 0 or 1 whether the element is in it or not, and then array[1] qwould equal the actual location, making the code look like thiss:
if (contains(array, element1)[0] > -1){
// do something
} else if (contains(array, element2)[0] > -1) {
// do something
} else if (contains(array, element3)[0] > -1) {
// do something
}...
I can say screw the if-else block, save the return of contains in a variable and run several if-statements.
Solution one will search through my array at least twice. Solution two will search at least as many times as there are elements I'm looking for. Solution 3 is perhaps the best, but maybe not the most elegant. Solution 4 will run each if statement...
What is the best way to search just once? Should I make a function that takes all the things I am looking for and returns an array with the position of each element? Am I overthinking it?
I would modify contains to only use the return value to indicate the error/success of the find, and, if the parameter was found, output the parameter by reference.
int contains(int *data, int value, int *loc)
{
for(int i = 0; i < SIZE; i++)
{
if(data[i]==value)
{
*loc = i;
return 1; // success
}
}
*loc = -1;
return 0; // failure
}
Now, you can just do:
int elem1loc, elem2loc, elem3loc;
if(contains(data, val1, &elem1loc))
// use elem1loc...
if(contains(data, val2, &elem2loc))
// use elem2loc...
You could pass a pointer to say int which would be populated when the contains function finds an element. Then inside your if block you would be assured that pos is the correct index.
Example:
int pos;
if (contains(array, element1, &pos) > -1) {
// Here you can check pos for the position
} else if (contains(array, element2, &pos) > -1) {
// Here you can check pos as well...
}
Here's a solution that doesn't require you to modify contains at all:
int pos;
if ((pos = contains(array, element1)) > -1) {
// do something with pos
} else if ((pos = contains(array, element2)) > -1) {
// do something with pos
} else if ((pos = contains(array, element3)) > -1) {
// do something with pos
}
This works because variable assignment in most imperative languages is an expression.

bitwise right shift affecting another short

I am using bitwise operators to shift the binary value of shorts within a linked list. The function is recursive and after an arbitrary number of occurrences, my right shift seems to affect the value of a short in the next link despite me not pointing to this link at all at this point of the function. Here is my code :
static void move_right(t_tetri *piece) {
int i;
i = 0;
piece->x_offset++;
while (i < piece->height) {
piece->shape[i] = piece->shape[i] >> 1;
i++;
}
}
int ft_solve(t_map *map, t_tetri *list) {
if (list == NULL) return (1);
while (list->y_offset + list->height <= map->size) {
while (list->x_offset + list->width <= map->size) {
if (put_tetri(map, list)) {
set_piece(map, list);
if (ft_solve(map, list->next)) return (1);
else unset_piece(map, list);
}
move_right(list);
}
reset_piece(list);
}
list->y_offset = 0;
return (0);
}
piece->shape is an array containing 4 short but I'm mostly concerned about the first of these here. In certain cases (not all) when I go through the move_right function the value of piece->next->shape[0] is shifted in the same way, which poses a big problem for the next recursion of ft_solve.
Would anyone have any idea?
I can post more of my code if necessary, I'm not really used to ask questions here so if you need more information I'm ready to add it.

Count occurences of a subarray in a bigger array using recursion

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

How do you use a string array in a conditional statement in C?

I want to use a string array in an if statement to test whether the input string matches any of the strings in the array.
So far this is what I've tried:
void checkForError(char input[50])
{
const char *input2[]={"print","loadStarter","terminate()"};
if(input != input2)
{
printf("Error:Incorrect method '%s'.\n",input);
}
else
{
abort();
}
}
And if I were to enter something in the array like "print" it would end up showing me:
Error:Incorrect method 'print'.
but when I try something not listed in the array like "g" it repeats the error message nonstop.
I was thinking perhaps something like this could work:
void checkForError(char input)
{
if(strcmp(input,"print"))!=0 || strcmp(input,"loadStarter"))!=0 || strcmp(input,"terminate()")
{
printf("Error:Incorrect method '%s'.\n");
}
else
{
abort();
}
}
But it turns out that actually doesn't work so what do I do?
You cannot compare strings (usefully) in C using == and !=; you must use library functions such as strcmp instead. See How to compare strings in an "if" statement? for details.
I think a good solution to your question would be to loop around your array, aborting on the first match.
void checkForError(char* input)
{
const char *input2[]={"print","loadStarter","terminate()"};
const int len = sizeof(input2)/sizeof(input2[0]);
for (int i = 0; i < len ;i ++)
{
if (strcmp(input,input2[i]) == 0)
{
//I have matched the string input2[i]
abort();
}
}
// Nothing matched
printf("Not found\n");
}
This would also be easier to extend than any handcoded method.
Also, if you plan on doing a lot with these strings, and you have a limited number of strings, you should probably turn them into some sort of enum. This way you do not have to have strcmp scattered everywhere, and you can use a standard switch statement.
a better method would be to have a return value then have your error message depend on return value.
// return 1 when string is OK, 0 otherwise:
int checkForError(const char* input)
{
if(!strcmp(input,"print")) || !strcmp(input,"loadStarter")0 || !strcmp(input,"terminate()")
{
return 1;
}
else
{
return 0;
}
}
Your second thought is correct, you should not compare the strings using == operator, anyway, I'm not sure whether the rest is a typo or not, but it should be like that:
void checkForError(char * input)
// ^ note the * (pointer)
{
if(strcmp(input,"print")!=0 || strcmp(input,"loadStarter")!=0 || strcmp(input,"terminate()") != 0)
// you forgot brackets
{
printf("Error:Incorrect method '%s'.\n", input);
// ^ you forgot the "input" parameter
}
else
{
abort();
}
}

Resources