1

次のことをどのように行うべきかを理解するのに苦労しています:

次のように定義された単語のリストがあります。

typedef struct _StringNode {
  char *str;
  struct _StringNode* next;
} StringNode;

ここで、文字列と同じ長さの 2 つの単語リストを受け取る関数を作成する必要があります。また、文字列の最初のリストからの単語のすべての出現を、2 番目のリストからの対応する単語に置き換える必要があります。

例:

        text: "stack overflow siteoverflow oveflow stack"
    patterns: [ "stack", "overflow", "site" ]
replacements: [ "Hello", "guys", "here" ]
      result: "Hello guys hereguys guys Hello"

単語ごとに: 使用しようとしているstrstr()ので、文字列のコピー内の単語の出現へのポインターを取得してから、単語を変更し、テキスト文字列のコピーのポインターを昇格させます。

char* replace(const char *text,
              const StringNode *patterns,
              const StringNode *replacements);
4

2 に答える 2

1

これを使用できます

char *strnreplace(char *st,const int length, 
                  const char *orig,const char *repl) {

  static char buffer[length];
  char *ch;

  if (!(ch = strstr(st, orig)))
      return st;

  strncpy(buffer, st, ch-st);
  buffer[ch-st] = 0;
  sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
  return buffer;
}


void replace(const char *text,
              const StringNode *patterns,
              const StringNode *replacements)
{
  StringNode *pat, *rep;
  char *temp = text;
  int length = strlen(text);
  for( pat = patterns, rep = replacements;
        pat->next != NULL;
        pat = pat->next, rep = rep->next ) {
        temp = strnreplace(temp, length, pat->str, rep->str);
  }
}
于 2012-07-20T11:16:55.637 に答える
0

おそらくこのようなもの:

char* replace(const char *text,
              const StringNode *patterns,
              const StringNode *replacements)
{
  char *out = malloc(1024), *put = out;

  while(*text != '\0)
  {
    const StringNode *piter, *riter;
    int found = 0;

    /* Check if current start of text matches any pattern. */
    for(piter = patterns, riter = replacements;
        piter != NULL;
        piter = piter->next, riter = riter->next)
    {
      const size_t plen = strlen(piter->str);
      if(strncmp(text, piter->str, plen) == 0)
      {
        /* Hit found, emit replacement. */
        const size_t rlen = strlen(riter->str);
        memcpy(out, riter->str, rlen);
        out += rlen;
        text += plen;
        found = 1;
        break;
      }
    }
    if(!found)
      *put++ = *text++;
  }
  *put = '\0';

  return out;
}

上記はバッファオーバーフローを処理しないことに注意してください。簡潔にするために省略しています。動的文字列データ型の上にこのようなものを実装して、コア操作(追加)で必要に応じて宛先文字列を自動的に拡張することをお勧めします。

UPDATEコメントに応えて、上記が実装しようとしているアルゴリズムは次のとおりです。

set output to empty string
while text remaining
  if start of text matches pattern[i]
    append replacement[i] to output
    remove len(pattern[i]) characters from start of text
  else
    append first character of text to output
    remove first character of text

したがって、に何かが残っている限り、パターンの一致を繰り返しtextチェックします。

于 2012-07-20T09:23:25.703 に答える