I am trying to reverse a word using recursion in c and i got upto this.
#include<stdio.h>
void reverse(char *a){
if(*a){
reverse(a+1);
printf("%c",*a);
}
}
int main() {
char a[] = "i like this program very much";
reverse(a); // i ekil siht margorp yrev
return 0;
}
Suppose the input string is i like this program very much. The function should change the string to much very program this like i
Algorithm:
1) Reverse the individual words, we get the below string.
"i ekil siht margorp yrev hcum"
2) Reverse the whole string from start to end and you get the desired output.
"much very program this like i"
I have successfully completed up-to step 1 and i am not sure how to proceed further. Please help.
To help you out without giving too much away, I think your algorithm is too complicated. Instead of reversing individual words and then reversing the whole string, consider splitting the string into an array of strings with space as a delimiter. Then simply reverse the array.
The way to do this in C is a little bit odd; since you already use char arrays as strings, you actually need to make an array of char arrays. For example:
char a[] = "i like this program very much";
actually means
a = ['i', ' ', 'l', 'i', 'k', 'e', ' ', ... , 'c', 'h']
So, you want to create an array of char arrays so it now looks like this:
new_array = [['i'], ['l', 'i', 'k', 'e'], ... ['m', 'u', 'c', 'h']]
Then all you need to do is print the new array backwards, and you've got the output you want!
#include <stdio.h>
#include <ctype.h>
void swap(char *a, char *b){
char wk = *a;
*a = *b;
*b = wk;
}
void strpartrev(char *top, char *tail){
while(top < tail)
swap(top++, tail--);
}
void step1(char *a){
while(isspace(*a))
++a;
if(!*a)
return;
char *top =a;
while(a[1] && !isspace(a[1]))
++a;
char *tail = a;
strpartrev(top, tail);
step1(a+1);
}
int step2(char *str, int pos){
char ch = str[pos];
return (ch == '\0')? 0 : ((str[pos=step2(str, ++pos)]=ch), ++pos);
}
void reverse(char *a){
step1(a);
step2(a, 0);
}
int main() {
char a[] = "i like this program very much";
reverse(a);
puts(a);//much very program this like i
return 0;
}
The program for outputting the words in reverse has a very similar structure to the program you already have. Instead of making a recursive call at each individual character, though, make a recursive call at each word. Then instead of printing the character after your recursive call, you print the word. The recursion stops when you have reached the end of the string, indicating you have found the last word.
In pseudo-code:
reverse_words(string a)
start_of_word = a;
a = end_of_word(a);
if (a is not at end of string)
reverse_words(a)
print start_of_word up to a
#include <stdio.h>
#include <string.h>
// copy substring of str from [start] to [first occurance of ' '] into buf
void substr(char *str, int start, char* buf){
int end, strLength = strlen(str);
end = start;
do{
if(str[end-1] == ' ' || end == strLength){
strncpy(buf, str+(start*sizeof(char)), end-start);
buf[end-start] = '\0';
return;
}
end++;
}while(1);
}
void reverse(char *a){
if(strlen(a)==0){
return;
}
if(*a){
reverse(a+1);
printf("%c",*a);
}
}
void rec(char *str, int start){
if(start >= strlen(str)){
return;
}
char buf[32];
substr(str, start, buf);
rec(str, start + strlen(buf)+1);
reverse(buf);
}
int main(int argc, char* argv[]) {
char *str = "asd123 qwe kutu chu-chu";
rec(str, 0);
printf("\n");
return 0;
}
Related
i'm trying to reverse a string using recursion and a single pointer to that string.
My idea is to traverse the string from both edges, raising the pointer and inserting '\0's at the end of the string. For example - given a string 'abcde\0' - replace "chars" before the middle of the string, and insert '\0' after -> recursive calls -> when "stop condition" is reached, original string should be like this - 'edc\0\0\0' - and half of chars stored as temp variable, in stack. When turning back and popping the stack, these chars should overwrite the '\0' in reverse order. This is the idea.
This is my code so far, but I can't get it work - please help me understand, what do I miss. I have a '\0' in the middle of string that I can't figure out how to rewrite it. (I guess this is the major problem)
Thanks in advance.
#include <stdio.h>
#include <string.h>
void rev_str(char* _str);
int main()
{
char str[]="abcde";
puts("Str before:");
puts(str);
rev_str(str);
puts("Str after");
puts(str);
return 0;
}
void rev_str(char* _str)
{
int len=strlen(_str);
char temp=*_str;
if(len>1)
{
*_str = _str[len-1];
_str[len-1]='\0';
rev_str(++_str);
}
_str[len-1]=temp;
}
I won't debug your code, however this might help you understand things better -
http://www.programmingsimplified.com/c-program-reverse-string
Examples taken from page -
C program to reverse a string using pointers
Now we will invert string using pointers or without using library function strrev.
#include<stdio.h>
int string_length(char*);
void reverse(char*);
main()
{
char string[100];
printf("Enter a string\n");
gets(string);
reverse(string);
printf("Reverse of entered string is \"%s\".\n", string);
return 0;
}
void reverse(char *string)
{
int length, c;
char *begin, *end, temp;
length = string_length(string);
begin = string;
end = string;
for (c = 0; c < length - 1; c++)
end++;
for (c = 0; c < length/2; c++)
{
temp = *end;
*end = *begin;
*begin = temp;
begin++;
end--;
}
}
int string_length(char *pointer)
{
int c = 0;
while( *(pointer + c) != '\0' )
c++;
return c;
}
C program to reverse a string using recursion
#include <stdio.h>
#include <string.h>
void reverse(char*, int, int);
int main()
{
char a[100];
gets(a);
reverse(a, 0, strlen(a)-1);
printf("%s\n",a);
return 0;
}
void reverse(char *x, int begin, int end)
{
char c;
if (begin >= end)
return;
c = *(x+begin);
*(x+begin) = *(x+end);
*(x+end) = c;
reverse(x, ++begin, --end);
}
rev_str(++_str);
This is the problem. You're modifying _str here so when you do _str[len-1]=temp at the end, you're writing to the wrong location. Change it to
rev_str(_str + 1);
Just change the code rev_str(++_str); into rev_str(_str+1);. The ++_str equal to _str += 1, it will change the pointer char *_str. But _str+1 will only initialize the formal param, and will not change the 'char *str'. I hope this can help you.
I want to write a recursive function in C languge that revers a word. I know how to do it with printing it, but actually reversing the original word I don't know how.
so, I want to write a function that revers a word, using pointers, using string.h, but has to be void, no printing, and changing the original word. the function prototype:
void reverse(char* string);
what I was able to write were the stop terms of the recursion(and i'm not sure if they are correct);
if(!string) return; // if the string is empty
if(*(string+1)=='\0' return (*string); // if there is only on char in the string
if(*(string+2))=='\0' // if there are only 2 letters In the strings-swap
temp=(*string);
(*string)= * (string+1);
(*string+1)= temp; // I don't know what to do after..
that would be great is go guys can explain to me what to do.
thank you.
An implementation with tail recursion:
#include <stdio.h>
#include <string.h>
/* function prototypes */
void reverse(char *string);
void reverseWorker(char *string, int start, int end);
int main(int argc, const char *argv[]) {
char string[] = "Hello, world.";
printf("string (original) = %s\n", string);
/*
reverse(string);
Or, to reverse each word in the string...
*/
char *ptr = strtok(string, " ");
while(ptr != NULL) {
reverse(ptr);
ptr = strtok(NULL, " ");
if(ptr != NULL)
*(ptr-1)=' ';
}
/* the rest is the same */
printf("string (reversed) = %s\n", string);
return 0;
}
void reverse(char *string) {
reverseWorker(string, 0, strlen(string)-1);
}
void reverseWorker(char *string, int start, int end) {
/* terminal condition */
if(start>=end)
return;
/* swap */
char temp = string[start];
string[start]=string[end];
string[end]=temp;
/* recursive step */
reverseWorker(string,start+1,end-1);
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void reversefill(char*const from,char*const to){
if(from>=to){
//Nothing to do. Odd lengths get to from==to.
//Even lengths 'swap over'.
//Pointer comparison guaranteed legit - in the same array.
return;
}
//Textbook swap.
//Could use the classic xor swap trick.
//However that will just confuse in this example.
const char temp=*from;
*from=*to;
*to=temp;
//Carry on moving our 'work' points closer together from both ends.
reversefill(from+1,to-1);
}
void reverse(char* str){
const size_t sz=strlen(str);
if(sz==0){
return;//Can't use str-1 - UB.
//Could head for the door if sz==1 but this is a training example on recursion.
//So we'll just show it works if from==to.
}
reversefill(str,str+sz-1);
}
int main() {
char*const str="Hello World!";
char*const rev=malloc(strlen(str)*sizeof(*str));//sizeof not required but good habit
strcpy(rev,str);
reverse(rev);
printf("%s\n",rev);
free(rev);//Don't listen to smart-arses who say that's unnecessary.
//Unless you really need to use the trick...
//However examples should be the cleanest possible code.
return EXIT_SUCCESS;
}
I think the requirement was in-place reversal.
The only way to do that (I think the OP realises) is to work from the ends and swap 'symmetric' positions. That is swap the first with last, second with second last, etc.
That's fine but we need to realise when we've 'met' in the middle.
That's obvious of odd length cases - the two working points meet.
For even cases we need to spot the workings 'crossing over'.
That's exactly how reversefill(,) works.
I think this code is an excellent specimen of the strengths and weaknesses of C strings.
The main function is fantastically efficient.
But actually has to scan the string twice because C doesn't intrinsically provide a O(1) way of obtaining the length of a string!
You could write the function like
void reverse( char s[] )
{
reverse_impl( s, strlen( s ) );
}
void reverse_impl( char s[], size_t n )
{
if ( !( n < 2 ) )
{
char c = s[0];
s[0] = s[n-1];
s[n-1] = c;
reverse_impl( s + 1, n - 2 );
}
}
But it is a wrong solution because it is not function void reverse( char s[] ); that is a recursive function. It is function void reverse_impl( char s[], size_t n ); that is recursive. But according to your assignment it is function void reverse( char s[] ); that has to be recursive.
So the correct solution is the following.
#include <stdio.h>
void reverse( char s[] )
{
if ( *s )
{
char *p = s;
char c;
do
{
c = *p;
*p = *( p + 1 );
*( p + 1 ) = c;
} while ( *p++ );
reverse( s );
c = *p;
*p = *( p - 1 );
*( p - 1 ) = c;
}
}
int main( void )
{
char s[] = "abcde";
puts( s );
reverse( s );
puts( s );
return 0;
}
The output is
abcde
edcba
This recursive function uses neither standard function :)
I am attempting to complete a homework assignment, part of which is to design a function that inserts a string into another string. All functions, with the exception of strlen(), are off limits to me. Specifically the problem is this: I am having trouble implementing the part of the function that "makes room" in the target string for the inserted string. Inserting the string always results in a trampling of array elements. Can anyone point out what I am doing wrong here? Thanks for helping me learn!
Edit: Integer n is the location in the string that I am supposed to insert the other string.
void insertstring(char *str, char *ins, int n)
{
int i;
int scoot=strlen(ins);
char *p=str+n;
for (i=strlen(str); i > n; --i) { //This is where I'm doing it wrong I think
str[i+scoot]=str[i]; //
}
do {
*p = *ins;
++p;
++ins;
}
while (*ins != '\0');
}
An elegant solution uses reversing to achieve the desired result. Assume your target string, str, is composed of two blocks, AB, where A is the block before the insertion point, and B is the block after insertion point. Furthermore, assume that the string to insert, ins, is denoted by a third block C.
It can be seen that if you concatenate C to AB and then reverse B, reverse C, and reverse both B and C, you get ACB, which is the desired result. More explicitly, this is what you have after appending C to AB:
ABC
And this is what you want:
ACB
ACB can be obtained by:
Reverse B, to get B_r (B reversed);
Reverse C, to get C_r - at this point we have AB_rC_r;
Reverse both B and C, that is, compute A(B_rC_r)_r, which yields ACB.
Here's the code that implements this algorithm:
void reverse(char *, char *, char *);
/* Insert string C between blocks AB in str */
void insertstring(char *str, char *ins, int n) {
/* 1 - Append C to the end of str */
int i = strlen(str);
char *p = str+i, *q = ins;
while ((*p++ = *q++));
p--;
/* 2 - Reverse C and B */
reverse(str, str+i, p-1); /* C */
reverse(str, str+n, str+i-1); /* B */
/* 3 - Reverse B_rC_r */
reverse(str, str+n, p-1);
}
void reverse(char *str, char *begin, char *end) {
char tmp;
while (begin < end) {
tmp = *begin;
*begin = *end;
*end = tmp;
begin++;
end--;
}
}
And some sample code to test it:
#include <stdio.h>
#include <string.h>
int main() {
void insertstring(char *, char *, int);
char test[128] = "A string to test.";
printf("Before: %s\n", test);
insertstring(test, "hello!", 4);
printf("After: %s\n", test);
return 0;
}
This will insert "hello!" beginning in test[4]. Here's the output:
$ ./test
Before: A string to test.
After: A sthello!ring to test.
Consider taking this approach: the code is short and elegant. This technique is described in Programming Pearls, 2nd edition, as a good way to perform vector rotation. According to the author, Brian Kernighan and P.J. Plauger used precisely this method in their Software Tools in Pascal to move lines within a text editor.
First you have change
for (i=strlen(str); i > n; --i)
to
for (i=strlen(str); i >= n; --i)
because you have to move str[n] too.
The other problem is when you insert ins:
do {
*p = *ins;
++p;
++ins;
}
while (*ins != '\0');
Here you copy the terminating '\0' from ins to str so the rest is lost. Change it to
while (*ins != '\0') {
*p = *ins;
++p;
++ins;
}
After mentioning about n, update for loop as
for (i=n+scoot; i >= n; i--)
You want to move strlen(ins) number of character ahead from location n.
Tried it with single loop,
go to index , copy src content into temp_array and simultaneously copying medi into src
once medi is copied completely , start putting the content of temp_array till it become empty
void insert_in_middle (char *src, char *medi, int index)
{
int i=0, j = index, k=0;
char temp_array[50];
while(src[j] != '\0' || temp_array[k] != '\0')
{
temp_array[i] = src[j];
if(medi[i] != '\0')
{
src[j] = medi[i];
}
else if(temp_array[k] != '\0')
{
src[j] = temp_array[k];
k++;
}
i++; j++;
}
printf("src[%s]\n", src);
printf("medi[%s]\n",medi);
printf("temp_array[%s]\n",temp_array);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *str_ins();
int main()
{
char *test = "Hello, world!";
printf("%s\n",test);
str_ins(&test,strstr(test,"world"),"my ");
printf("%s\n",test);
}
char *str_ins(a, b, c) // insert string c into a at point b
char **a, *b, *c;
{
char *stemp;
int pos = strlen(*a) - strlen(b);
stemp = (char *) malloc(strlen(*a)+strlen(c)+1);
strncpy(stemp,*a,pos);
strcpy(stemp+pos,c);
strcat(stemp,b);
free(a);
*a = stemp;
return *a;
}
I am currently studying C and I can't get past this exercise. I must create a recursive function to reverse string1 into string2. Here is my code. I would gladly appreciate your help.
#include <stdio.h>
#define MAX 100
void reverse(char s1[],char s2[],int n,int j);
int main()
{
char string1[MAX]="How Are You Mate";
char string2[MAX]="";
int n=0;
int i=0;
int j=0;
for(i=0;string1[i]!='\0';i++)
n++;
reverse(string1,string2,n,j);
printf("String-a normal:\n%s\n",string1);
printf("String-a reverse:\n%s\n",string2);
return 0;
}
void reverse(char s1[],char s2[],int n,int j)
{
if(n>0)
{
s2[j]=s1[n];
reverse(s1,s2,n-1,j+1);
}
else
s2[j]='\0';
}
in-place (the caller could make a copy of the string before calling this function) string reverse with tail-recursion
void reverse (char *str, size_t len)
{
char tmp;
if (len-- < 2) return;
tmp = *str;
*str = str[len];
str[len] = tmp;
reverse (str+1, len -1);
}
O, if you don't want pointers:
void reverse (char str[], size_t len)
{
char tmp;
if (len-- < 2) return;
tmp = str[0];
str[0] = str[len];
str[len] = tmp;
reverse (str+1, len -1);
}
The reversing starts by copying the n-th character of string1 array into string2. The n-th character happens to be the null terminator. It becomes the first character of your new string, so the string looks empty to all standard C routines, including printf.
Calling
reverse(string1,string2,n-1,j);
from the main should fix the problem. The condition in the reverse should be changed from if(n>0) to if(n>=0) as well.
Although it does not save the resulting string anywhere, you get the idea.
#include <stdio.h>
void rev (const char* str);
int main () {
const char str[] = "!dlrow ,olleH";
printf("%s\n", str);
rev(str);
printf("\n");
return 0;
}
void rev (const char* str) {
char c = *str;
if (c != '\0') {
rev(str + 1);
printf("%c", c);
}
}
I have corrected the program. Please find the changes below
void reverse(char s1[],char s2[],int n,int j)
{
if(n>0)
{
s2[j]=s1[n-1];
reverse(s1,s2,--n,++j);
}
else
s2[j]='\0';
}
i recommend using library , size=strlen(array) in stead of
for(i=0;string1[i]!='\0';i++)
n++;
to count how many characters in arra
I have the following code:
#include <stdio.h>
void insertion_sort(char[], int);
void swap(char*, char*);
int main() {
char s[] = "hello world";
puts(s);
insertion_sort(s, sizeof(s)/sizeof(char));
puts("done\n");
puts(s);
return 0;
}
void swap(char* a, char* b) {
char tmp = *a;
*a = *b;
*b = tmp;
}
void insertion_sort(char s[], int n)
{
int i,j;
/* counters */
for (i=1; i<n; i++) {
j=i;
while ((j>0) && (s[j] < s[j-1])) {
swap(&s[j],&s[j-1]);
j = j-1;
}
printf("%s\n", s);
}
}
The problem is, after the insertion_sort() function call, s becomes empty - puts(s) prints nothing.
Please advise.
Change:
insertion_sort(s, sizeof(s)/sizeof(char));
to:
insertion_sort(s, strlen(s));
otherwise you will be including the '\0' terminator of s[] in your sort.
Note that you will need an additional header for strlen so change:
#include <stdio.h>
to:
#include <stdio.h> // printf etc
#include <string.h> // strlen etc
The problem is that the length that you pass to insertion_sort includes terminating \0 character, which happens to have value 0, so in sort it is placed as the first element of your array. This is why your last puts() prints nothing - because the first character is now "the end of a string".
I suggest you to calculate the size of a string using strlen() which will return the length of a string excluding terminating character. Or if you want to do it your way, take terminating character into consideration and substract it from the total length.