在 C++ 中删除字符串中的连续重复字符

Posted

技术标签:

【中文标题】在 C++ 中删除字符串中的连续重复字符【英文标题】:Removing consecutive repeated characters in a string in C++ 【发布时间】:2011-08-07 13:54:17 【问题描述】:

这是一个字符串问题。首先删除所有长度为1的重复连续子字符串,然后删除长度为2的子字符串,依此类推... 例如,如果我们有这样的字符串 -> abcababceccced 删除长度为 1 的子字符串后,我们将得到 abcababceced 删除长度为 2 的子字符串后,我们将得到 abcabced 删除长度为 3 的子字符串后,我们将得到 abced 这将是最终输出

我设计了一个算法,但它的复杂度为 O(n3),这根本不可取。我的算法如下

char str[20]="abcababceccced";
int len=strlen(a);
 for(i=1;i<=len/2;i++)
     for(j=0;j<len;)
      bool flag=chk(a,j,i);//this function will check whether the substring starting at a[j] and a[j+i] of length i are same or not.
       if(flag)
        //remove the second same substring.
       
       else 
         j=j+i;
      
  

如果有人在 C++ 中针对这个特定问题提出一种不太复杂的算法,我将不胜感激。

【问题讨论】:

【参考方案1】:

您可以通过相对于自身“滑动”字符串、逐个字符进行比较,然后查找匹配的位置来构建一些东西。例如:

abcababceccced
-abcababceccced
-0000000001100-

abcababceced
--abcababceced
--0001100110--

不清楚它是否会更快,“按顺序”,但只是以不同的方式看待问题。

【讨论】:

【参考方案2】:

确实,每个子字符串长度都可以使用线性时间,因为您只需要连续相同的子字符串。只需将计数器保留一个相同的字符,并在找到子字符串时更新字符串。由于您要删除所有可能长度的子字符串,因此总体复杂度是二次的。

以下 C 代码应该可以工作:

char str[20]="abcababceccced";
int len = strlen(str);
int i, j, counter;
for(i = 1; i <= len / 2; ++i)

   for(j = i, counter = 0; j < len; ++j)
   
      if (str[j] == str[j - i])
         counter++;
      else
         counter = 0;
      if (counter == i)
      
         counter = 0;
         memmove(str + j - i, str + j, (len - j) * sizeof(char));
         j -= i;
         len -= i;
      
   
   str[j] = 0;
   printf("%s\n", str);

这应该连续打印:

abcababceced
abcabced
abced

【讨论】:

【参考方案3】:

你可以一次性完成:

#include <stdio.h>
#include <string.h>

int main()

  char str[] = "abbbbcaaaababbbbcecccedeeed";
  int len = strlen(str);
  int read_pos, write_pos, prev_char;

  prev_char = str[0] + 1;
  for (read_pos = 0, write_pos = 0; read_pos < len; read_pos++)
  
    if (str[read_pos] != prev_char)
    
      str[write_pos] = str[read_pos];
      write_pos++;
    
    prev_char = str[read_pos];
  
  str[write_pos] = '\0';

  printf("str = %s\n", str);
  return 0;

由于您总是写入小于或等于读取位置的位置,因此您永远不会在使用之前销毁字符串。

我已将 prev_char 初始化为与第一个字符完全不同的东西,但检查字符串的长度是否不为零是有意义的。

【讨论】:

这只是第一遍。 @AShelly:你完全正确。随意投反对票:-(。我觉得可以使用后缀树非常有效地解决原始问题。像这样:citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.6378 为什么不将其添加到您的答案中而不是邀请反对票:)

以上是关于在 C++ 中删除字符串中的连续重复字符的主要内容,如果未能解决你的问题,请参考以下文章

从 std::string 中删除特定的连续字符重复

如何删除字符串中的重复项

在 C++ 中使用 stringstream 获取字符串中的所有 N 个连续字符

tr命令

怎么用JS把特定字符串重复的字符删除留下一个

c++ 怎样提取一个字符串中的连续数字并放到另一个数组中保存? 急!