它是一个字符串问题。首先删除长度为1的所有重复连续子字符串,然后删除长度为2的子字符串,依此类推...... 例如,如果我们有这样的字符串 - > abcababceccced 删除长度为1的子字符串后,我们将获得abcababceced 删除长度为2的子字符串后,我们将被删除 删除长度为3的子字符串后,我们将被删除 这将是最终输出
我设计了一种算法,但它的复杂度为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 ++中为这个问题提出一个不太复杂的算法,我将非常感激。
答案 0 :(得分:1)
您可以通过相对于自身“滑动”字符串来构建内容,比较字符到字符,然后查找匹配的位置。例如:
abcababceccced
-abcababceccced
-0000000001100-
abcababceced
--abcababceced
--0001100110--
不清楚它会更快,“顺序”,但只是一种不同的方式来看问题。
答案 1 :(得分:0)
你可以一次通过:
#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
初始化为与第一个字符完全不同的内容,但检查字符串的长度是否为零是有意义的。
答案 2 :(得分:0)
实际上,每个子字符串长度都可以实现线性时间,因为您只需要连续相同的子字符串。只需将计数器保留为相同的字符,并在找到子字符串时更新字符串。由于您要删除所有可能长度的子字符串,因此总体复杂度是二次的。
以下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