演習 4-1

無職の間にK&Rを再読。演習問題の解答をさらす。解く順番は適当。

演習 4-1
s における t の最も右側の出現位置を返す関数 strrindex(s, t) を書け。


Exercise 4-1
Write the function strrindex(s, t), which returns the position of the rightmost occurrence of t in s, or -1 if there is none.


ちょっとセコイ(?)けど、一旦 strlen で文字列の長さを求めて、ケツのほうから評価していく。入れ子になっている for の条件式は外れそうな順番で並べる。

#include <stdio.h>
#include <string.h>

int strrindex(const char s[], const char t[])
{
  int i, j, k;
  int slen, tlen;

  slen = strlen(s) - 1;
  tlen = strlen(t) - 1;

  for (i = slen; i >= 0; i--) {
    for (j = tlen, k = i; t[j] == s[k] && j >= 0 && k >= 0; j--, k--)
      ;
    if (j == -1) return k + 1;
  }
  
  return -1;
}

int main(void)
{
  //                   1         2
  //         012345678901234567890123
  char *s = "this is his first issue.";
  
  printf("%2d ==  0?\n", strrindex(s, "this"));  
  printf("%2d ==  8?\n", strrindex(s, "his"));
  printf("%2d == 18?\n", strrindex(s, "is"));
  printf("%2d == 20?\n", strrindex(s, "sue."));
  printf("%2d == -1?\n", strrindex(s, "sthi"));
  printf("%2d == -1?\n", strrindex(s, "e.t"));
  
  return 0;
}


strlen を使わないならこんな感じ。一番右側かどうかは最後までわからないので、あんま効率よくない。

int strrindex(const char s[], const char t[])
{
  int i, j, k;
  int ret = -1;

  for (i = 0; s[i] != '\0'; i++) {
    for (j = i, k = 0; s[j] == t[k] && t[k] != '\0' && s[j] != '\0'; j++, k++)
      ;
    if (t[k] == '\0') ret = i;
  }
  return ret;
}