Flip Array Recursively - c

There is this problem on LeetCode that I can not get to work in C/C++
The idea is to reverse an array in its place (using no other additional array) using recursion.
The link is : https://leetcode.com/explore/learn/card/recursion-i/250/principle-of-recursion/1440/
The solution is done in Java or Python.
I tried implementing the solution in C but I always get the original array, my code is as follows:
void reverseString(char* s, int sSize){
if(!s)
return;
reverseString(s+1,sSize-1);
s[sSize] = *s;
}
There is something I am not accounting for. Please let me know how would you solve it, and if possible why this is not working. Thanks.

I'll take a stab at this.
The general idea for a recursive solution is for each call to get a pointer to the start of a string, and how many characters to look at, and this walks its way to the middle of the string.
void reverseString(char *start, int n)
{
if (n <= 1) return;
char tmp = start[0];
start[0] = start[--n]; // the nth character is start[n-1]
start[n] = tmp;
reverseString(++start, --n);
}
On each recursive call, the starting string pointer is incremented by one, and the length decreased by two.
FIRST CALL: v v
hello, world
SECOND CALL: ^ ^
The common danger area is making sure it does the right thing with even and odd-length strings.
This method is a bit simpler with just two parameters, and - as some might say - a bit more elegant :-) even if the ++ and -- could be considered tricky (one increment and two decrements).
EDIT: This version is also tail recursive, which can lead to certain optimizations by internally turning it into a loop.

Solution (thank you to the folks in the comments):
void reverse(char * str, int len)
{
char tmp;
if (len <= 1)
return;
tmp = str[0];
len--;
str[0] = str[len];
str[len] = tmp;
str++;
reverse(str, len-1);
}
Call this function with your initial string and 0 as arguments:
char str[] = "Ding dong";
reverse(str, 0, strlen(a));

void reverse_string(char *x, int start, int end)
{
char ch;
if (start >= end)
return;
ch = *(x+start);
*(x+start) = *(x+end);
*(x+end) = ch;
//Function calling itself: Recursion
reverse_string(x, ++start, --end);
}
In this function we are passing the string, the starting index and the ending index.... The recursion will continue till start>=end i.e. till the center of the string appears..... And everytime it will swap the 2 indexes i.e. from the start and from the end...

Related

C recursive function to reverse a string without pointers, string.h, or external variables [duplicate]

There is this problem on LeetCode that I can not get to work in C/C++
The idea is to reverse an array in its place (using no other additional array) using recursion.
The link is : https://leetcode.com/explore/learn/card/recursion-i/250/principle-of-recursion/1440/
The solution is done in Java or Python.
I tried implementing the solution in C but I always get the original array, my code is as follows:
void reverseString(char* s, int sSize){
if(!s)
return;
reverseString(s+1,sSize-1);
s[sSize] = *s;
}
There is something I am not accounting for. Please let me know how would you solve it, and if possible why this is not working. Thanks.
I'll take a stab at this.
The general idea for a recursive solution is for each call to get a pointer to the start of a string, and how many characters to look at, and this walks its way to the middle of the string.
void reverseString(char *start, int n)
{
if (n <= 1) return;
char tmp = start[0];
start[0] = start[--n]; // the nth character is start[n-1]
start[n] = tmp;
reverseString(++start, --n);
}
On each recursive call, the starting string pointer is incremented by one, and the length decreased by two.
FIRST CALL: v v
hello, world
SECOND CALL: ^ ^
The common danger area is making sure it does the right thing with even and odd-length strings.
This method is a bit simpler with just two parameters, and - as some might say - a bit more elegant :-) even if the ++ and -- could be considered tricky (one increment and two decrements).
EDIT: This version is also tail recursive, which can lead to certain optimizations by internally turning it into a loop.
Solution (thank you to the folks in the comments):
void reverse(char * str, int len)
{
char tmp;
if (len <= 1)
return;
tmp = str[0];
len--;
str[0] = str[len];
str[len] = tmp;
str++;
reverse(str, len-1);
}
Call this function with your initial string and 0 as arguments:
char str[] = "Ding dong";
reverse(str, 0, strlen(a));
void reverse_string(char *x, int start, int end)
{
char ch;
if (start >= end)
return;
ch = *(x+start);
*(x+start) = *(x+end);
*(x+end) = ch;
//Function calling itself: Recursion
reverse_string(x, ++start, --end);
}
In this function we are passing the string, the starting index and the ending index.... The recursion will continue till start>=end i.e. till the center of the string appears..... And everytime it will swap the 2 indexes i.e. from the start and from the end...

Substring function in C with malloc returning incorrect value

I am implementing a parser in C for first order logic formulas. To check for a binary connective formula (i.e. in the form (A BinaryConnective B)) I need to split the string and check if A and B are formulas. I have done this using a subString function and I call it from partone and parttwo (A and B respectively):
char *partone(char *g) {
//Given the formula (A*B) this returns A
return subString(g, 1, binPosition(g));
}
char *parttwo(char *g) {
//Given the formula (A*B) this returns B
return subString(g, binPosition(g) + 1, strlen(g) - 1);
}
The substring function is the following:
char *subString(char *g, int start, int end) {
//the substring includes index start but does not include the end index.
char *substr = malloc(sizeof(char)*(end - start));
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
return substr;
}
This works when I pass any function except a negated formula (we are using the character "-" to denote negation). For example when I pass (-X[xz]>X[yz]), the program returns "Not a Formula", but if I write the same without the negation it works perfectly. The problem is that the substr that is returned for partone() is "-X[xz]$" where $ can be any random character that I think was stored in memory before. Any ideas why this is happening ONLY in this case? I am new to C and I have looked everywhere.
Thanks in advance.
You forgot the terminating NUL in your subString function. Your malloc should look like
char* substring = (char*)malloc (sizeof (char)*(end-start+1));
And at the end you need to terminate the result with 0:
substring [end-start]=0;
And since arrays in c are zero-indexed, I'm suprised that you don't lose the leading "-" of part A, since partone calls subString with 1 as start.
EDIT: there are a lot of built-in functions for string manipulation in C/C++. You should use them since they are tested and optimised. I did not use C so much for many years now so I'm not up to date what are the appropriate methods in C++11 today, but Google may tell you.
EDIT: As chux pointed out, the meaning of your end parameter is not fully clear. So you need to check the strlen (g)-1 in parttwo or the loop conditions in subString and increase to +2 in my malloc statement`.
OP's use of start and end is not formalized, but I'll assume they are indexes into the string of the first and last character of the desired sub-string.
Recall in C, array indexes begin with 0 as in g[0] is the first character of the string stored at g.
If that case, code needs to allocate end - start + 1 + 1 space and insure the allocated character array has a null character '\0' at the end.
char *subString(const char *g, int start, int end) {
if (end < start || start < 0) {
return NULL;
}
size_t size = 2u + end - start;
char *substr = malloc(size);
if (substr) {
int i;
for(i = 0; i < (end - start); i++) {
substr[i] = g[start + i];
}
substr[i] = '\0';
}
return substr;
}
Other simplifications/improvements possible

How to check if a string exists in an array of character arrays

I'm looking for a way to check if a specific string exists in a large array of strings. The array is multi-dimensional: all_strings[strings][chars];. So essentially, this array is an array of character arrays. Each character array ends in '\0'
Given another array of characters, I need to check to see if those characters are already in all_strings, kind of similar to the python in keyword.
I'm not really sure how to go about this at all, I know that strcmp might help but I'm not sure how I could implement it.
As lurker suggested, the naive method is to simply loop on the array of strings calling strcmp. His string_in function is unfortunately broken due to a misunderstanding regarding sizeof(string_list), and should probably look like this:
#include <string.h>
int string_in(char *needle, char **haystack, size_t haystack_size) {
for (size_t x = 0; x < haystack_size; x++) {
if (strcmp(needle, haystack[x]) == 0) {
return 1;
}
}
return 0;
}
This is fairly inefficient, however. It'll do if you're only going to use it once in a while, particularly on a small collection of strings, but if you're looking for an efficient way to perform the search again and again, changing the search query for each search, the two options I would consider are:
If all_strings is relatively static, you could sort your array like so: qsort(all_strings, strings, chars, strcmp);... Then when you want to determine whether a word is present, you can use bsearch to execute a binary search like so: char *result = bsearch(search_query, all_strings, strings, chars, strcmp);. Note that when all_strings changes, you'll need to sort it again.
If all_strings changes too often, you'll probably benefit from using some other data structure such as a trie or a hash table.
Use a for loop. C doesn't have a built-in like Python's in:
int i;
for ( i = 0; i < NUM_STRINGS; i++ )
if ( strcmp(all_strings[i], my_other_string) == 0 )
break;
// Here, i is the index of the matched string in all_strings.
// If i == NUM_STRINGS, then the string wasn't found
If you want it to act like Python's in, you could make it a function:
// Assumes C99
#include <string.h>
#include <stdbool.h>
bool string_in(char *my_str, char *string_list[], size_t num_strings)
{
for ( int i = 0; i < num_strings; i++ )
if (strcmp(my_str, string_list[i]) == 0 )
return true;
return false;
}
You could simply check if a string exists in an array of strings. A better solution might be to actually return the string:
/*
* haystack: The array of strings to search.
* needle: The string to find.
* max: The number of strings to search in "haystack".
*/
char *
string_find(char **haystack, char *needle, size_t max)
{
char **end = haystack + max;
for (; haystack != end; ++haystack)
if (strcmp(*haystack, needle) == 0)
return *haystack;
return NULL;
}
If you're wanting the behavior of a set, where all strings in the array are unique, then you can use it that way:
typedef struct set_strings {
char **s_arr;
size_t count;
size_t max;
} StringSet;
.
.
.
int
StringSet_add(StringSet *set, const char *str)
{
// If string exists already, the add operation is "successful".
if (string_find(set->s_arr, str, set->count))
return 1;
// Add string to set and return success if possible.
/*
* Code to add string to StringSet would go here.
*/
return 1;
}
If you want to actually do something with the string, you can use it that way too:
/*
* Reverse the characters of a string.
*
* str: The string to reverse.
* n: The number of characters to reverse.
*/
void
reverse_str(char *str, size_t n)
{
char c;
char *end;
for (end = str + n; str < --end; ++str) {
c = *str;
*str = *end;
*end = c;
}
}
.
.
.
char *found = string_find(words, word, word_count);
if (found)
reverse_str(found, strlen(found));
As a general-purpose algorithm, this is reasonably useful and even can be applied to other data types as necessary (some re-working would be required of course). As pointed out by undefined behaviour's answer, it won't be fast on large amounts of strings, but it is good enough for something simple and small.
If you need something faster, the recommendations given in that answer are good. If you're coding something yourself, and you're able to keep things sorted, it's a great idea to do that. This allows you to use a much better search algorithm than a linear search. The standard bsearch is great, but if you want something suitable for fast insertion, you'd probably want a search routine that would provide you with the position to insert a new item to avoid searching for the position after bsearch returns NULL. In other words, why search twice when you can search once and accomplish the same thing?

More optimized solution, find number of substrings in a string. Using C

So, I have a task to find number of substrings in given string. I can't use any C libraries for doing this task. stringExist can only have 2 strings as a parameters.
My solution is working, but I have a feeling that there should be a more elegant way to do this task.
Solution 1: as it turns out, it doesn't work correctly
#include <stdio.h>
int stringExist(char string[], char s2[]);
int main(void){
char string[] = "strstrASDstrSTRst";
char s2[] = "str";
printf("Final result: %i\n",stringExist(string,s2));
return 0;
}
int stringExist(char string[], char s2[]){
/* I am aware that I can init all this values in one row */
int count = 0;
int size = 0;
int i = 0;
int temp = 0;
int result = 0;
while(s2[size]!='\0'){
size++;
}
while(string[i]!='\0')
{
if(string[i]==s2[0])
{
printf("Found first occurrence\n");
count=0;
while((temp=(string[i]==s2[count]))!=0)
{
count++;
if(size==count){
printf("Match\n");
result++;
break;
}
i++;
}
}
i++;
}
return result;
}
Solution number 2:
So far no errors found.
Did a little bit different string traversal, now I don't increment i in the compare chars loop.
#include <stdio.h>
int stringExist(char string[], char s2[]);
int main(void){
char string[] = "bobobobojkhhkjjkhbo;klkl;bobo";
char s2[] = "bobo";
printf("Final result: %i\n",stringExist(string,s2));
return 0;
}
int stringExist(char string[], char s2[]){
int count = 0;
int size = 0;
int i = 0;
int c = 0;
int temp = 0;
int result = 0;
while(s2[size]!='\0'){
size++;
}
for(i=0;string[i]!='\0';i++){
if(string[i]==s2[0])
{
printf("Found first occurence at %i\n",i);
count = 0;
c = i;
while((temp=(string[c]==s2[count]))!=0)
{
printf("Count %i, I %i, current char: %c\n",count, c,string[c]);
count++;
if(size==count){
printf("Match\n");
result++;
break;
}
c++;
}
}
}
return result;
}
Thanks for you suggestions,
Vitaly
beat it: (also works for the extra condition)
int stringExist( char *string, char *sub )
{
int count = 0;
while( *string )
{
char *a = string, *b = sub;
while( *a && *a == *b ) {a++;b++;}
count += !*b;
++string;
}
return count;
}
I suggest writing it the way you would if you were allowed to use library functions. Then go back and write your own versions of those library functions that you used. While writing highly optimized versions of the string.h functions may be difficult, writing decent versions of most of them them in C is pretty easy..
Using subroutines (functions) to preform sub-tasks of this problem will help you to keep your code clear and also avoid certain types of problems, such as if you called:
x = stringExist("aaaaa", "aa");
There are 4 occurances of the string "aa" within "aaaaa", but I don't think that your function will find all of them. The reason for this is that as you search through the larger string for occurances of the second you are using the same index for both the beginning of the string and within the string. In fact, it looks like you would get the wrong results for:
x = stringExist("tBatBath", "tBath");
Unless of course, I've misunderstood what the function was supposed to do.
If you were to write your own version of a string prefix comparing function (essentially memcmp or strncmp) then you would have separated the job of matching the length of the string from looking deeper into the string and probably would not have made such a mistake.
If you are worried about squeezing efficiency out of your functions and the overhead of calling functions, don't. First, it's not that bad. Second, just declare them inline or static inline and if you compile with optimization turned on the compiler will most likely generate code as good as it would have without the use of multiple functions.
This feels like a homework question - in which case you should definitely just do it yourself. But, something that you'll probably want to check for that I don't think your code is handling correctly now is this:
How many times does "bobo" appear in the string "bobobo". It should probably be twice and I think your code as is will only count one.
Good luck,
Mark.
Well, from an algorithmic point of view, it's not bad. You can make optimizations, but I don't think that's the point (looks like homework!).
You may have a slight issue: in a string like "hahahaha", how many times should "haha" be detected? Twice? Thrice? Your code would see it twice.
From a stylistic point of view, there's certainly room for improvement, but you'll learn that over time, from coding and reading other's code =). Keep at it!

Some questions concerning a C integer to string function

Whilst reading through K&R, I came across the integer to string function. I gave it a quick read, and decided to implement it myself, but instead of printing, it updates a character array.
Here is what I have
void inttostr(int number, char str[]) {
static int i;
if (number / 10) {
inttostr(number / 10, str);
}
str[i++] = number % 10 + '0';
}
It seemed to work for the few integers I gave it, but I have some questions.
I haven't explicitly included the nul byte \0 at the end, so why does the string work fine when printed with printf("%s\n", str);?
I don't think I'm very good at thinking recursively. When I try and step through the program in my mind, I lose track of what is still awaiting execution. Is there a better way of seeing what is happening internally, to help me learn?
Any other suggestions on the code?
I'm using Xcode.
This is not homework. I'm just learning.
Thanks!
You're correct that you're never writing NUL, which is a bug.
In general, you don't have to think through the entire solution. You just have to make sure every step is correct. So in this case, you say:
1 . inttostr(number / 10, str);
will take care of all but the last digit.
2 . Then I will take care of the last one.
You can trace what's happening, though. For e.g. 54321 it looks like:
inttostr(54321, str); // str = ...;
inttostr(5432, str); // str = ...;
inttostr(543, str); // str = ...;
inttostr(54, str); // str = ...;
inttostr(5, str); // str = ...;
str[0] = '5'; // str = "5...";
str[1] = '4'; // str = "54...";
str[2] = '3'; // str = "543...";
str[3] = '2'; // str = "5432...";
str[4] = '1'; // str = "54321...";
Note that when you don't return from any of the functions until you write the first character, then you return in the opposite order from the calls.
The ... signifies that you haven't NUL-terminated. Another issue is that you're using a static variable, so your code isn't reentrant; this means it breaks in certain scenarios, including multi-threading.
To address the reentrancy and NUL issue, you can do something like the code below. This creates a helper function, and passes the current index to write.
void inttostr_helper(int number, char str[], int *i)
{
if (number / 10) {
inttostr_helper(number / 10, str, i);
}
str[(*i)++] = number % 10 + '0';
str[*i] = '\0';
}
void inttostr(int number, char str[])
{
int i = 0;
inttostr_helper(number, str, &i);
}
EDIT: Fixed non-static solution.
I am impressed of the creativity to use recursive, despite that it is not necessary. I think the code should remove statically-allocated i variable because this variable will persist through calls. So the second time you use this function from your code, e.g. from main(), it will not be initiated and will be the same value from previous call. I would suggest using return value as follow:
int inttostr(int number, char *str) {
int idx = 0;
if (number / 10) {
idx = inttostr(number / 10, str);
}
str[idx++] = number % 10 + '0';
return idx;
}
1, Your compiler (especially in debug mode) may have filled str with 0. Unix does this if you allocate memory with new() - But don't rely on this, either set the first byte to \0 or memset everything to 0
2, paper + pencil. Draw a table with each variable across the top and time down the side.
3, Write the simplest, longest version first, then get clever.
I haven't explicitly included the nul byte \0 at the end, so why
does the string work fine when printed
with printf("%s\n", str);?
how is the original char array declared when you call your function the first time? if it is a static char array then it will be filled with 0's and that would explain why it works, otherwise its just "luck"
I don't think I'm very good at thinking recursively. When I try and
step through the program in my mind, I
lose track of what is still awaiting
execution. Is there a better way of
seeing what is happening internally,
to help me learn?
honestly, I am not sure if anybody is good in thinking recursively :-)
Did you try drawing the execution step by step?

Resources