【问题标题】:Searching for block of characters (word) in a text在文本中搜索字符块(单词)
【发布时间】:2018-06-18 20:30:17
【问题描述】:

我想在文本中搜索一个字符块(单词)。
例如,我有下一个文本“Hello xyz world”,我想搜索“xyz”,注意单词后面的空格。

// The Text
const char * text = "Hello xyz world";
// The target word
const char * patt = "xyz ";
size_t textLen = strlen(text),
  pattLen = strlen(patt), i, j;

for (i = 0; i < textLen; i++) {
  printf("%c", text[i]);
  for (j = 0; j < pattLen; j++) {
    if (text[i] == patt[j]) {
      printf(" <--");
      break;
    }
  }
  printf("\n");
}

结果必须如下:

但不幸的是,结果如下:

它收集了整个文本中所有相似的字符,而不仅仅是目标字符(单词)。

如何解决这个问题?

【问题讨论】:

  • 只是不要忽视显而易见的事情:string.h 有函数 strstr 可以完成这项工作。
  • @ZenJ:是的,我知道,但我无法操作字符串。

标签: c string algorithm search


【解决方案1】:

您必须在打印之前进行完整的子字符串匹配;在第一次通过时标记适用的字符,然后在第二次通过以打印结果。在您的情况下,您将创建第二个数组,其布尔值对应于第一个数组,类似于

text = "你好 xyz 世界"; 匹配 000000111100000

我假设你可以在网上找到一个基本的子串匹配程序。第二遍打印会很容易:您已经掌握了逻辑。而不是if (text[i] == patt[j]),只需使用if match[i]

这足够暗示吗?

【讨论】:

  • 如果在找到完全匹配后保留第一个匹配字符的索引,则不需要数组。
  • 我也考虑过这个解决方案,我认为它比我更好,所以我支持你:)
  • @usr2564301 是的,这基本上就像我的解决方案,但我更喜欢这种方法
  • 谢谢。 Is that enough of a hint?如果有一个简单的例子,那就太好了。
  • 那么您需要超出 Stack Overflow 明确规定的帮助。我建议一些在线教程来帮助你了解语言和设计细节,也许还有当地的同学或导师。
【解决方案2】:

在开始打印任何&lt;-- 之前,您需要确保完全匹配。并且为了避免在patt 上通过数组末尾进行访问,当数组中剩余的字符少于pattLen 时,您必须停止搜索。

然后当你找到完全匹配时,你可以打印patt的内容跟&lt;--和增加pattLen-1的指针位置。最后,您将不得不从文本中复制剩余的字符。

代码可能变成:

// The Text
const char * text = "Hello xyz world";
// The target word
const char * patt = "xyz ";
size_t textLen = strlen(text),
    pattLen = strlen(patt), i, j;

for (i = 0; i <= textLen - pattLen; i++) {  // don't search if less that pattLen remains
    printf("%c", text[i]);
    if (text[i] == patt[0]) {               // first char matches
        int found = 1;                      // be optimistic...
        for (j = 1; j < pattLen; j++) {
            if (patt[j] != text[i + j]) {
                found = 0;
                break;                      // does not fully match, go on
            }
        }
        if (found) {                        // yeah, a full match!
            printf(" <--");                 // already printed first char
            for (j = 1; j < pattLen; j++) {
                printf("\n%c <--", patt[j]);// print all others chars from patt
            }
            i += pattLen - 1;               // increase index...
        }
    }
    printf("\n");
}
while (i < textLen) {
    printf("%c\n", text[i++]);              // process the end of text
}

以上代码给出了"xyz ""llo" 的预期输出...

【讨论】:

  • 谢谢,但在某些情况下,例如“world”、“rld”,它们不能很好地工作。看看online compiler
  • @LionKing:我的错,我忘了控制文本字符串末尾的搜索模式是什么=> 需要&lt;= 而不是&lt;。以前的代码过早停止了一步。由编辑修复。
【解决方案3】:

您应该从头开始检查模式的每个字母(而不是检查整个模式)。试试这个(未测试):

int currIndex = 0;

for (i = 0; i < textLen; i++) {
  printf("%c", text[i]);
  if (text[i] == patt[currIndex]) {
      for (j = 0; j < pattLen; j++) {
          if(text[i+j] != patt[j]){
              continue;
          }
      }
      printf(" <--");
      currIndex++;
      if(currIndex==pattLen)
          currIndex = 0;
  }
  else{
      currIndex = 0;
  }
  printf("\n");
}

注意:不是实现这一目标的最佳方法,但您的示例最简单

注意2:这个问题应该按原样结束:

寻求调试帮助的问题(“为什么这段代码不起作用?”)必须 包括期望的行为、特定的问题或错误以及 在问题本身中重现它所需的最短代码。 没有明确问题陈述的问题对其他人没有用处 读者。见:How to create a Minimal, Complete, and Verifiable example.

【讨论】:

  • 干得好,但您的代码在某些情况下不能正常工作。例如,当我将目标词更改为“llo”时,结果是The result。关于您的注释 2,我认为我的问题很明确,没有模棱两可。
  • @LionKing 是的,你是对的,当我检测到单词的结尾时,我不会重置 currIndex。我知道你的问题很清楚,但看起来你没有足够的搜索解决方案并且太早发布了一个问题:) 但也许我错了(我编辑了我的答案,但当索引超出范围时它没有出错?)
  • 谢谢,但很遗憾,问题依然存在。
  • @LionKing SO 上的人无法解决您的所有问题...抱歉:/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
  • 2011-12-27
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多