评价我的(C ++)代码:递归strstr sans任何标准库字符串函数:)

时间:2009-12-27 00:23:37

标签: c++ recursion

所以,这个想法是写一个递归函数,比较两个字符串,看看字符串'prefix'是否包含在字符串'other'中,不使用任何标准字符串函数,并使用指针算法。以下是我想出的。我认为它有效,但很奇怪 - 这有多优雅,1-10级,你会做过的任何明显的时髦动作呢?

感谢。

bool is_prefixR(char* prefix, char* other) {
  static int prePos = 0,othPos = 0; 
  //  static int othPos = 0;
  bool test;
  test = ( *(prefix+prePos) == *(other+othPos)); //checks to see if same

  if (!*(prefix+prePos)) { return 1; } //end of recursion
  if (!*(other+othPos)) { return 0; }

  if (!test) {
    othPos++; //move othPos pointer by 1
    prePos = 0; //reset the prefix position
    return(is_prefixR(prefix, other)); //lets try again
  } else { //chars are the same
    othPos++; //move othPos pointer by 1
    prePos++;
    return(is_prefixR(prefix, other)); //lets try again
  }
    return 0;
}

7 个答案:

答案 0 :(得分:11)

  1. 这对所有字符串都无法正常工作。例如:prefix =“aab”,other =“aaab”

    • 不要使用静态变量。由于它们,第二次调用该函数时会失败。

    • 不要使用递归:对于长字符串,您可以获得堆栈溢出。请改用循环。

    • 名称“prefix”用于出现在另一个字符串开头的字符串 - 这不是这里的情况。

答案 1 :(得分:4)

它是凌晨1点,对于理解代码来说已经很晚了,但是这样一个简单的函数应该很容易理解而你的代码却不容易理解。编写函数时的静态变量并不是一个好主意,因为它们使调试难以置信,因为函数不再成为无状态函数。尝试将您需要的值传递给下一个函数,如果您发现不能,请尝试以不同的方式编写它。您也以错误的方式使用了前缀。我认为你的意思是子串。

我提出了下面的两个函数,它们可以执行您想要的操作,并且除了非空终止的字符串之外的所有内容都相当简单。它并不是那么快,因为即使is_substr短于othersub也会继续尝试进行比较。你似乎表示优雅是游戏的名称,所以我避免了所有增加的复杂性 注意:is_substr取决于is_prefix

bool is_prefix(const char* prefix, const char* other) {
    if ( *prefix == 0 ){
        return true;
    }else if ( *other == 0 || *prefix != *other ){
        return false;
    }
    return is_prefix(++prefix, ++other);
}

bool is_substr(const char* const sub, const char* other) {
    if ( *other == 0 ){
        return false;
    }else if ( is_prefix(sub, other) ){
        return true;
    }
    return is_substr(sub, ++other);
}

只是为了让您了解输出功能

is_substr("aab", "aaab"); //1
is_substr("ab", "ba"); //0
is_substr("aab", "a"); //0
is_substr("a", "bab"); //1

is_prefix("a", "a"); //1
is_prefix("a", "ab"); //1
is_prefix("ab", "a"); //0
is_prefix("aab", "aaab"); //0

答案 2 :(得分:2)

size_t pos = string1.find(string2);

相比,我的优雅是0

标准库是有原因的。用它。即使您想创建strstr,这是一个C函数而不是C ++函数,您实际上也不需要避免使用strcmp。即便如此,在一个单独的函数中自己实现strcmp也会使这一点更加清晰。 最重要的是,您的static变量使此功能只能使用一次。你做错了。

从你的措辞来看,听起来这可能是一个功课问题?在这种情况下,您应该添加家庭作业标签,并准确说出要求是什么。

答案 3 :(得分:1)

使用

static int prePos = 0,othPos = 0;

使此功能不是线程安全的。你确定那是你想要的吗?

othPos将永远增长,所以此功能仅在第一个之后有效 时间othPos不会以0的价值开头。

我认为如果你要使用指针,那么你应该增加指针并传递修改后的指针而不是传递基指针并让所有工作都发生在静态int中。

答案 4 :(得分:0)

也许删除所有不必要的parens?但即使这样,我也会在优雅的赌注中把它归零。优雅函数必须做的第一件事是执行一个任务,并对函数进行描述 - “比较两个字符串以查看字符串'prefix'是否包含在字符串'other'中”根本没有任何意义。前缀必须以字符串开头,不包含在其中。

答案 5 :(得分:0)

//伪代码

if prefix == 0
   return true
else if other == 0
   return false
else return (*prefix == *other) && is_prefix(1+prefix, 1+other);

答案 6 :(得分:-3)

如果你想使用递归(糟糕的想法,但让我们暂时暂停判断),你可以做得更干净:

bool is_prefixR(char* prefix, char* other) {
  if (!*prefix) return true;
  if (*prefix != *other) return false;
  return is_PrefixR(prefix+1, other+1);
}