开发者

Find the rightmost occurrence of a string t, in a string s

Corrected code:开发者_运维技巧

int strrindex(char *s, char *t) {
  int i, j, k, p;

  i = -1;
  for (k = 0; s[k] != '\0'; k++) {
    if (strlen(s) < strlen(t)) break;
    if (s[k] == t[0]) {
      for (p = k; s[p] != '\0'; p++) {
    j = p;
        while (s[j] != '\0' && s[j] == t[j-k] && t[j-k] != '\0') { j++; } 
        if (t[j-k] != '\0') { break; }
    i = k;
      }
    }
  }

  printf("%d\n", i);
  return 0;
}


  for (p = k; s[p] != '\0'; p++) {
    while (s[p] == t[p] && t[p] != '\0') { p++; }

At this point, you are comparing string s starting at position p with string t starting at position 0. So it shouldn't be t[p], but instead t[p - k].

    if (s[p] != t[p] || t[p] != '\0') { i = -1; }

You don't need this at all - if the current section doesn't match, you just leave i at the last match. (which will anyway be -1 if there has been no match so far)


I think this should work:

 int strrindex(char *s, char *t) {

  int i = -1;
  int j = 0;
  int k = 0;
  for (; s[k]; k++) {
    if(!t[j]) {
      i = k - j;
      j = 0;
    }
    if (s[k] != t[j])
      j = 0;
    else
      j++;
  }
  if(!t[j + 1])
    i = k - j - 1;

  return i;
}


  • Your loop over p is indexing both s[p] and t[p]. That's incorrect, since they're both different indices.
  • Your if (s[p] != t[p] ...) i = -1; has no effect, because you then immediately set it to k.


You're not the first person to want such a function.

See: Is there a reverse fn() for strstr? for some example implementations.


There's a great reference on substring search algorithms here: http://www-igm.univ-mlv.fr/~lecroq/string/index.html

With any of them, you can simply switch things around to start with pointers to the last byte of the string and negate the indices.


There are several bugs in your code. Here are the ones I've found:

  1. You're using p, which is way into s, as an index into the beginning of t. You want to reference t[p-k] instead.
  2. Using p in the inner while loop interferes with the operation of p in the for loop. In fact, you don't need the for loop on p, since the outer for loop takes care of iterating through s.
  3. The while loop doesn't have any guard for when you reach the end of s, so it's pretty easy to run off of the end of s (have a partially matched t at the end of s).
  4. (s[p] != t[p-k] || t[p-k] != '\0') will evaluate to true when t[p-k] == '\0', which is wrong – it's OK if s keeps going after t stops. You can simplify this to just (t[p-k] != '\0').
  5. Setting i to -1 will wipe out any previous find you've made. This is wrong – an invalid match should not invalidate a previous valid match. If you get rid of the extra inner for loop, this can just turn into a continue statement.
  6. i=k needs an else clause so it doesn't wipe out i=-1, or i=-1 needs to break/continue out of the current iteration.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜