简体   繁体   中英

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 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[pk] 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[pk] || t[pk] != '\\0') will evaluate to true when t[pk] == '\\0', which is wrong – it's OK if s keeps going after t stops. You can simplify this to just (t[pk] != '\\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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM