递归删除重复字符

时间:2017-09-09 08:42:47

标签: c recursion

我试图编写一个递归函数,以递归方式从给定字符串中删除所有重复的字符。 例如" Hello world" - > " Helo wrd"。

我的限制是:

  1. 不允许循环。
  2. 不能再向原始函数添加参数(remove_duplicates)。
  3. 不允许使用string.h库中的函数,尽管我可以递归地编写它们。
  4. 我允许使用其他辅助递归函数。

    到目前为止我写的函数只适用于短字符串,它调用函数的次数太多了。任何建议如何提高效率?

    void remove_duplicates3(char string[], int index)//(str,RecursiveStrlen(str, 0)-1)
    {
        int length = RecursiveStrlen(string + 1, 0);
        if (string[index] == '\0' || index == 0)
        {
            return;
        }
    
        if (string[0] != string[index])
        {
            remove_duplicates3(string, index - 1);
        }
        else
        {
            BackspaceString(string, index);
            remove_duplicates3(string, length - 1);
        }
    
        remove_duplicates3(string + 1, length - 1);
    }
    
    int RecursiveStrlen(char str[], int index)
    {
        if (str[index] == '\0') 
            return index;
        return RecursiveStrlen(str, index + 1);
    }
    
    
    void BackspaceString(char string[],int index)//deletes one char from string in a specific index
    {
        if (string[index] == '\0')//end of string
            return;
        string[index] = string[index + 1];
        BackspaceString(string, index + 1);
    }
    

4 个答案:

答案 0 :(得分:0)

如果可以使用全局变量来存储结果字符串,则可以执行以下操作:

char result[30]="";
char over[30]="";


int check(char *over, char c)
{
    if(*over != '\0')
    {
        if(*over == c)
        {
            return 1; //exists
        }
        else
        {
            return check(over+1, c);
        }
    }
    return 0; //doesn't exist
}

int strLen(char *str)
{
    if(*str=='\0')
    {
        return 0;
    }
    return strLen(str+1)+1;
}

void remove_duplicates(char *str)
{
    if(*str != '\0')
    {
        if(check(over, *str)==0)
        {
            int len=strLen(result);
            result[len++]=*str;
            result[len]='\0';

            len=strLen(over);
            over[len++]=*str;
            over[len]='\0';
        }
        remove_duplicates(str+1);
    }
}

结果字符串存储在result中,over是一个字符串,它将已经遇到的字符存储为字符串。如果在over中找不到check(),则c函数会针对字符0检查c以返回over

check()检查over的值,以确定其c中是否存在其参数over

remove_duplicates()将检查输入字符串str中的每个字符。如果之前未在str中遇到该字符,则会将其添加到已遇到的字符列表over中,并附加到result字符串。

直到输入字符串str结束为止。

答案 1 :(得分:0)

纯递归解决方案:

void remove_char(char string[], char c, int read_index, int write_index) {
    if (string[read_index] == 0) {
        string[write_index] = 0;
        return;
    }
    if (c == string[read_index]) {
        remove_char(string, c, read_index + 1, write_index);
    } else {
        string[write_index] = string[read_index];
        remove_char(string, c, read_index + 1, write_index + 1);
    }
}

void remove_duplicates(char string[], int index) {
    if (string[index] != 0 && string[index + 1] != 0) {
        remove_char(string, string[index], index + 1, index + 1);
        remove_duplicates(string, index + 1);
    }
}

答案 2 :(得分:0)

如果您的字符串只有ASCII字符 -

int arr[256] = {0};

/*
 * str - Input string
 * presult - Pointer to the buffer contain result
 */
void remove_duplicates(char *str, char *presult)
{
    if(*str != '\0')
    {
        if(arr[*str] == 0)
        {
            *presult = *str;
            arr[*str] = 1;
            remove_duplicates(str+1, presult+1);
        }
        remove_duplicates(str+1, presult);
    }
}

答案 3 :(得分:0)

简单的递归解决方案

我最初是在Scheme中编写此函数的,但已为您将其翻译为C。

/*
 * @params
 * src  ->  input string from which to remove duplicates
 * dest ->  output string (initially empty)
 * iter ->  elements visited (initially 0)
 */
void remove_Dups_recursively(char *src, char *dest, int iter){

    if(strlen(src) <= 1){
      dest = src;
      return;
    }

    if(iter == strlen(src)){
        return;
    }


   if(strchr(dest, src[iter]) == NULL){
       dest[strlen(dest)] = src[iter]; 
       iter++;
       remov(src, dest, iter);
   }

   else{
       iter++;
       remov(src, dest, iter);
   }
}