1

我很难理解我应该如何执行以下操作:

我有一个这样定义的单词列表:

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

现在我需要编写一个函数来接收一个字符串和两个相同长度的单词列表,并且我需要用第二个列表中的相应单词替换字符串中第一个列表中出现的每个单词。

例子:

        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;
}

请注意,上面不处理缓冲区溢出,为简洁起见省略。我建议在动态字符串数据类型之上实现类似的东西,以使核心操作(附加)根据需要自动增长目标字符串。

更新作为对评论的回应,上面试图实现的算法是:

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 回答