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 boths[p]
andt[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 tok
.
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:
- 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.
- 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.
- 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).
- (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').
- 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.
- 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.
精彩评论