【问题标题】:Better optimized way to search for a string更好的搜索字符串的优化方法
【发布时间】:2014-07-12 20:55:20
【问题描述】:

我有一个格式为联系人的字符串:

<abcde@123.343:5060;gr=xyz123>;+g134,<more_text>

我需要提取开&lt;和闭&gt;之间的内容 &lt;&gt; 可以有多个实例,但我必须从存在参数 gr= 的一对中获取内容(仅出现一次)。

为了解决这个问题,我所做的是:

ptr = strstr(str,"gr=");
if(ptr)
{
   temp1= ptr;
   while(*temp1 && *temp1!='<')
   {
      temp1--;
   }
   strncpy(newstring,temp1,ptr-temp1); //will copy upto start of gr
   temp2 = strstr(ptr,">")
   if(temp2)
     strncat(newstring,ptr,temp2-ptr); // copy remaining string till it finds closing '>'
}

它工作正常,但我想知道是否有避免while循环和倒退的方法?

【问题讨论】:

  • 是的,还有其他方法可以做到这一点,但您为什么认为它们会更好?您可以做的一件事是一次性构建newstring(从temp1temp2)。

标签: c substring


【解决方案1】:

您可以搜索 '' 的第一个匹配项,并查看 'gr=' 是否位于它们之间。

lt = strchr(ptr,'<');
gt = strchr(ptr,'>');
gr = strstr(ptr,"gr=");
if ( gr > lt && gr < gt) {
    strncat(newstring,lt,gt-lt);
}

【讨论】:

  • 由于 lt & gt 的搜索只是一个字符,您可以使用比 strstr 稍快的 strchr。无论如何,您的解决方案似乎比我的更有效和更简单。干得好。
  • @FabioCeconello,谢谢,即使是盲松鼠有时也会抓到坚果。
  • @CDahn 谢谢!真的很好的答案! :)
  • @chux 如果我写 strstr(ptr,'
  • @CDahn 你想要这个循环吗?因为否则如果 gr 参数不在第一对 这将不起作用!
【解决方案2】:

您可以使用 strcspn 获取到下一个标记的偏移量。您的代码没有寻找下一个实例的循环,但这段代码有。我假设您的循环不在此范围内,也许您需要适应一下。

size_t offset = 0, length;
offset = strcspn(str, "<");
while (str[offset] != '\0')
{
  ++offset;
  length = strcspn(str + offset, ">");
  ptr = strstr(str + offset, "gr=");
  if (ptr != NULL && ptr - str < offset + length)
  {
       strncpy(newstring, ptr + offset, length); 
       /* do what you need with newstring here */
  }
  offset = strcspn(str + offset + length + 1, "<");
}

【讨论】:

  • 谢谢!但我认为@CDahn 解决方案非常简单:)
【解决方案3】:

您可以通过只解析字符串一次而不是多次来做到这一点(与此处的其他答案不同)。如果子字符串没有任何重复字符,则下面的代码可以处理您提供的任何子字符串。

这个想法是复制任何&lt;&gt;之间的任何东西;复制时查找子字符串,如果找不到,则继续直到找到为止。

char *str = "<abcde@123.343:5060;gr=xyz123>;+g134,<more_text>";
char result[MAX_LENGTH];
size_t i = 0, j = 0;
char copying = 0, found = 0;
const char *subs = "gr=";
const int subs_len = 3;
while ((char ch = *str))
{
    if (ch == '<')
       copying = 1;
    else if (ch == '>')
    {
       if (found)
          break;
       else
       {
          copying = 0;
          i = j = 0;
       }
    }
    else if (copying)
    {
       result[i++] = ch;
       if (!found)
       {
          if (ch == subs[j])
          {
             ++j;
             if (j == subs_len)
                found = 1;
          }
          else
          {
             j = (ch == subs[0]) ? 1 : 0;
          }
       }
    }
    ++str;
}
result[i] = '\0';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-13
    • 1970-01-01
    • 1970-01-01
    • 2011-12-21
    • 2013-09-08
    • 2021-05-29
    • 1970-01-01
    相关资源
    最近更新 更多