Thread: recursive remove duplicates from a string

  1. #31
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i wrote this code like you said
    but i get these warnings
    warning C4717: 'remove_duplicates' : recursive on all control paths, function will cause runtime stack overflow

    and

    'not all control paths return a value'

    where is my mistake?
    Code:
    #include <stdio.h>
    void remove_duplicates(char string[], int index);
    void overwrite(char string[], int index);
    int has_duplicate(char string[], int index, char ch);
    
    
    int main()
    {
    	int i,ch;
    	char input[255];
    	printf("enter string\n");
     for (i = 0; i < 255 && (ch = getchar()) != '\n' && ch >=0; ++i)
        {
            input[i] = ch;
        }
    
        input[i] = '\0';
        remove_duplicates(input,0);
    	printf("%s",input);
    
       return 0;
    }
    
    
    void remove_duplicates(char string[], int index)
    {
        int flag=-1;
    	if (string[index]=='\0')
    	{
          //do nothing and return
    	}
    	flag=has_duplicate(string,index,string[index]);
        if (flag==1)
    	{
            overwrite(string,index);
            remove_duplicates(string,index);
    	}
    	else
    	{
            remove_duplicates(string,index+1);
    	}
    
    
    
    }
    int has_duplicate(char string[], int index, char ch)
    {
        int check;
    	if (index<0)
    	{
           return 0;
    	}
        if (ch==string[index])
        {
          return 1;
        }
    	else
    	{
           check=has_duplicate(string,index-1,ch); 
    	}
    	
       
    }//end func
    
    
    void overwrite(char string[], int index)
    {
         
    	if ( string[index]=='\0')
    	 {
          
    	 }
         if( string[index]!='\0')
    	 {
    		 string[index]=string[index+1];
    	     overwrite(string,index+1);
    	 }
    	 
    }

  2. #32
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    //do nothing and return
    is only a comment - it does NOT make function return

    computer does only what you TELL him to do, not what you want him to do
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #33
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    ye i know its what laser light said
    in the base case
    "do nothing and return"
    so i left empty cols

    i assumed thats what she ment
    Last edited by transgalactic2; 01-12-2009 at 11:56 AM.

  4. #34
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by transgalactic2 View Post
    ye i know its what laser light said
    in the base case
    "do nothing and return"
    so i left empty cols

    i assumed thats what she ment
    It means - you need to add return statement to actually force your function to return at this point
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #35
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    but its a void function
    there is no return in a void function

  6. #36
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    ye i know its what laser light said
    in the base case
    "do nothing and return"
    I have been generous to spell out the algorithm that I had in mind and implemented myself. You need to think about what the algorithm does and how it works, and from there implement the code, not blindly implement it. You cannot expect someone to provide you with the algorithm all the time, and my intention was to give you some idea of how it might be accomplished so that you can learn to construct such algorithms yourself.

    That said, if you had blindly implemented the algorithm I outlined you would have written:
    Code:
    if (string[index]=='\0')
    {
        return;
    }
    But why do that when you can negate the condition?
    Code:
    void remove_duplicates(char string[], int index)
    {
        int flag = -1;
        if (string[index] != '\0')
        {
            flag = has_duplicate(string, index, string[index]);
            if (flag == 1)
            {
                overwrite(string, index);
                remove_duplicates(string, index);
            }
            else
            {
                remove_duplicates(string, index + 1);
            }
        }
    }
    Note that the flag variable is unnecessary since you can check the return value of has_duplicate with:
    Code:
    if (has_duplicate(string, index, string[index]))
    EDIT:
    Oh, and I notice a slight but critical mistake in your call of has_duplicate: you need to use has_duplicate to check the part of the string before the current character. You are checking it before and including the current character.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #37
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    there is no return in a void function
    It could not return value.

    It still could use return statement to return control to the calling funtion
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  8. #38
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i changed the code like you said

    i dont get any out put
    ??

    Code:
    #include <stdio.h>
    void remove_duplicates(char string[], int index);
    void overwrite(char string[], int index);
    int has_duplicate(char string[], int index, char ch);
    
    
    int main()
    {
    	int i,ch;
    	char input[255];
    	printf("enter string\n");
     for (i = 0; i < 255 && (ch = getchar()) != '\n' && ch >=0; ++i)
        {
            input[i] = ch;
        }
    
        input[i] = '\0';
        remove_duplicates(input,0);
    	printf("%s",input);
    
       return 0;
    }
    
    
    void remove_duplicates(char string[], int index)
    {
        int flag = -1;
        if (string[index] != '\0')
        {
            flag = has_duplicate(string, index, string[index]);
            if (flag == 1)
            {
                overwrite(string, index);
                remove_duplicates(string, index);
            }
            else
            {
                remove_duplicates(string, index + 1);
            }
        }
    }
    
    
    
    int has_duplicate(char string[], int index, char ch)
    {
        int check;
    	if (index<0)
    	{
           return 0;
    	}
        if (ch==string[index])
        {
          return 1;
        }
    	else
    	{
           check=has_duplicate(string,index-1,ch); 
    	}
    	
       
    }//end func
    
    
    void overwrite(char string[], int index)
    {
         
    	if ( string[index]=='\0')
    	 {
            return;
    	 }
         if( string[index]!='\0')
    	 {
    		 string[index]=string[index+1];
    	     overwrite(string,index+1);
    	 }
    	 
    }

  9. #39
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Your has_duplicate function is incorrect since there is one control path where you do not return a value. The compiler warned you about that, didn't it?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #40
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    if you exit your input loop on the i < 255 condition -
    your assignment
    input[i] = '\0';

    will be out-of bounds access

    on first call to remove_duplicates it will call has_duplicate
    with index == 0 and passing string[0] as character.

    has_duplicate will check that the char matches itself - and return 1 (I suppose you will return this char - effectivly emptying all your string)
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #41
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i forgot to implement this last pat
    "else you call has_duplicate() for the previous character and return the return value of that recursive call."

    on this function:
    Code:
    int has_duplicate(char string[], int index, char ch)
    {
        int check;
    	if (index<0)
    	{
           return 0;
    	}
        if (ch==string[index])
        {
          return 1;
        }
    	else
    	{
               check=has_duplicate(string,index-1,ch);
               return check;
    	}
    	
       
    }//end func
    now dont have any warnings
    but i still dont have any output.
    ??
    Code:
    #include <stdio.h>
    void remove_duplicates(char string[], int index);
    void overwrite(char string[], int index);
    int has_duplicate(char string[], int index, char ch);
    
    
    int main()
    {
    	int i,ch;
    	char input[255];
    	printf("enter string\n");
     for (i = 0; i < 255 && (ch = getchar()) != '\n' && ch >=0; ++i)
        {
            input[i] = ch;
        }
    
        input[i] = '\0';
        remove_duplicates(input,0);
    	printf("%s",input);
    
       return 0;
    }
    
    
    void remove_duplicates(char string[], int index)
    {
        int flag = -1;
        if (string[index] != '\0')
        {
            flag = has_duplicate(string, index, string[index]);
            if (flag == 1)
            {
                overwrite(string, index);
                remove_duplicates(string, index);
            }
            else
            {
                remove_duplicates(string, index + 1);
            }
        }
    }
    
    
    
    int has_duplicate(char string[], int index, char ch)
    {
           int check;
    	if (index<0)
    	{
               return 0;
    	}
            if (ch==string[index])
            {
                return 1;
            }
    	else
    	{
               check=has_duplicate(string,index-1,ch);
    	   return check;
    	}
    	
       
    }//end func
    
    
    void overwrite(char string[], int index)
    {
         
    	if ( string[index]=='\0')
    	 {
                 return;
    	 }
              if( string[index]!='\0')
    	 {
    		 string[index]=string[index+1];
    	        overwrite(string,index+1);
    	 }
    	 
    }
    Last edited by transgalactic2; 01-12-2009 at 12:32 PM.

  12. #42
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The problem is here:
    Code:
    flag = has_duplicate(string, index, string[index]);
    Read my edit to post #36 and vart's post #40.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #43
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    you said
    " I notice a slight but critical mistake in your call of has_duplicate: you need to use has_duplicate to check the part of the string before the current character. You are checking it before and including the current character."


    i am doing the has duplicate check only once and its only for the current char

    i changed this line to
    Code:
    flag = has_duplicate(string, index, string[index-1]);
    and regarding the loop it worked fine before
    i just extended it to 255 char array
    it never gave me stack overflow bug
    ??

    i get no warnings
    and i dont have any output
    Code:
    #include <stdio.h>
    void remove_duplicates(char string[], int index);
    void overwrite(char string[], int index);
    int has_duplicate(char string[], int index, char ch);
    
    
    int main()
    {
    	int i,ch;
    	char input[255];
    	printf("enter string\n");
     for (i = 0; i < 255 && (ch = getchar()) != '\n' && ch >=0; ++i)
        {
            input[i] = ch;
        }
    
        input[i] = '\0';
        remove_duplicates(input,0);
    	printf("%s",input);
    
       return 0;
    }
    
    
    void remove_duplicates(char string[], int index)
    {
        int flag = -1;
        if (string[index] != '\0')
        {
            flag = has_duplicate(string, index, string[index-1]);
            if (flag == 1)
            {
                overwrite(string, index);
                remove_duplicates(string, index);
            }
            else
            {
                remove_duplicates(string, index + 1);
            }
        }
    }
    
    
    
    int has_duplicate(char string[], int index, char ch)
    {
           int check;
    	if (index<0)
    	{
               return 0;
    	}
            if (ch==string[index])
            {
                return 1;
            }
    	else
    	{
               check=has_duplicate(string,index-1,ch);
    	   return check;
    	}
    	
       
    }//end func
    
    
    void overwrite(char string[], int index)
    {
         
    	if ( string[index]=='\0')
    	 {
                 return;
    	 }
              if( string[index]!='\0')
    	 {
    		 string[index]=string[index+1];
    	        overwrite(string,index+1);
    	 }
    	 
    }

  14. #44
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Remember, you are trying to determine if there is a match with the current character. The current character is string[index], so passing string[index-1] is wrong. The problem is that you pass index as the second argument. This means that has_duplicate searches the part of the string from the first character to the current character... and so it will always return 1, causing the current character to be removed whether or it is a duplicate. As such, you should pass index - 1.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #45
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    thanks it worked

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. arrays vs lists? And containers in general!
    By clegs in forum C++ Programming
    Replies: 22
    Last Post: 12-03-2007, 02:02 PM
  3. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  4. Linked List Help
    By CJ7Mudrover in forum C Programming
    Replies: 9
    Last Post: 03-10-2004, 10:33 PM
  5. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM