卸下双支架

时间:2016-10-31 20:33:33

标签: c

非常基本,我在表格中有一些数据:(xxxxx)。 要删除括号:

long len = strlen(data);
for (int  i = 0; i < len - 2; ++i )
    data[i] = data[i + 1];
data[len - 2] = '\0';

哪个有效。 我还想处理另一个((xxxxxx))的案例,并在开始和结束时删除双"(("。 (而不是删除中间事件)。

假设对于每个 ((,最后还有))

是否有一种简单的方法可以修改此代码(或其他代码)来实现效率高

修改 这是一个数据解析,有3个选项:

XXXXXX, (XXXXX), ((XXXXX)

通常我会检查第一个字符是否为&#34;(&#34;,并应用此功能,现在我需要该功能以确保没有其他&#34;(&#34;,和如果有的话,为我自动删除它。 我不能两次应用该功能,因为如果我只有1&#34;(&#34;我将丢失数据。

6 个答案:

答案 0 :(得分:1)

假设您的数据总是超过3个字符......可能是这样的吗?

long len = strlen(data);
int ini = 0, end = 0;
// you know it starts with parenthesis
if ( data[0] == '(') {
    // check if it has double parenthesis at the beginning
    if ( data[1] == '(') {
        ini = 2;
        end = len - 2;
    }
    else {
        // It had only one parenthesis
        ini = 1;
        end = len -1;
    }
    // replace the data you need
    int  i = 0;
    for ( ; ini < end; ++i, ini++ )
        data[i] = data[ini];
    // "close" the "string"
    data[i] = '\0';
}

编辑:谢谢chqrlie,错过了那部分

答案 1 :(得分:1)

假设这只适用于字符串开头和结尾的parens ......

  • 如果少于两个字符,请停止。
  • 检查平衡的parens。
    • 在两端轻推字符串。
    • 递归。
char *strip_parens(char *string) {
    size_t len = strlen(string);
    if( len < 2 ) {
        return string;
    }

    char start = string[0];
    char end   = string[len-1];

    if( start == '(' && end == ')' ) {
        string[len-1] = '\0';
        string += 1;

        return strip_parens(string);
    }
    else {
        return string;
    }
}

这避免了必须复制整个字符串,但必须保留原始指针以便重新分配,否则它将泄漏内存。当字符串很大且剥离版本仅供临时使用时,这非常有用。

char *stripped = strip_parens(string);

/* do something with stripped */

free(string);  /* not stripped */

或者,您可以将它们放入结构中并管理结构。

任何更复杂的事情都应该look into using regular expressionsa grammar

答案 2 :(得分:1)

查看一对()字符串的开头和结尾。继续寻找,直到找不到一对。 (如果需要,限制为2个匹配)

效率:1向下运行字符串以查找其长度,1调用以移动字符串的内部。 O(n)

char *C_RemoveOuterBrackets(char *data) {
  char *src = data;
  size_t len = strlen(src);
  // Matching pair of () found
  while (src[0] == '(' && src[len - 1] == ')') {
    src++;
    len -= 2;
  }
  memmove(data, src, len);
  data[len] = '\0';
  return data;
}

处理"(())"""并且不需要假设两端匹配(剩余额外的parens)。

答案 3 :(得分:0)

您可以使用函数来计算括号。所以它会为更多的括号提供一个期望的(我猜)答案。

int countPar(char *s)
{
    int num = 0, i;
    for(i = 0; (i < strlen(s)) && (s[i] == '('); i++)
        num++;
    return num;
}

然后您只需执行以下操作

num = countPar(data)
for (int  i = 0; i < strlen(data) - 2 * num; ++i )
    data[i] = data[i + num];
data[len - 2 * num] = '\0';

随意纠正我,我实际上没有尝试过,只是算了。

答案 4 :(得分:0)

根据EOF评论:

void strip()
{

long len = strlen(data);
for (int  i = 0; i < len - 2; ++i )
    data[i] = data[i + 1];
data[len - 2] = '\0';

//RECURSIVE
if( data[0] == '(' )
 strip();


}

答案 5 :(得分:-1)

这是最优雅的方式(我现在可以想到):

int
main()
{
  char *data = strdup("((hello))");
  char *whead, *wtail;
  size_t len;

  len = strlen(data);
  whead = data;
  wtail = data + len - 1;
  while (*whead == '(' && *wtail == ')')
    {
      *wtail = '\0';
      whead++;
      wtail--;
      len--;
    }
  memmove(data, whead, len + 1);
  printf("%s\n", data);
  return (0);
}

如果您确定至少有开头的括号,那么您可以使用以下代码:

int
main()
{
  char *data = strdup("((hello))");
  size_t i;
  size_t len;

  len = strlen(data);
  for (i = 0; data[i] == '('; i++)
    ;
  memmove(data, data + i, len - (i * 2));
  data[len - (i * 2)] = '\0';
  printf("%s\n", data);
  return (0);
}