目录
问题介绍
我们有时会遇到一些让我们删除字符串重复字符的编程题,如输入字符串aabbb2323bb23,输出ab23b。在本篇博客中,我将介绍一种虽然算法复杂度比较高,但比较简单,容易实现的算法。
程序思路介绍
数据结构介绍
我们可以定义两个字符串数组,一个存储原来的输入的字符串,另一个则存放我们想要输出的字符串内容
算法介绍
如图所示,我们访问存储输入字符串数组A中每一个字符,我们要有选择选择性地放入另一个数组B中,即是看一看B数组中有没有这个字符,如果有就不存入B数组,如果没用就存入B数组。
思路很容易理解,以上图进行讲解,我们遍历位于上方的数组(数组A),第一个字符a,看一看这是下方的数组(数组B)有没有,这时下方数组(数组B)为空,则把a字符存储到下方数组(数组B),如此往复,直到遍历完上方数组(数组A),下方数组(数组B)即是我们想要的结果
代码实现
遍历数组对我们来说很简单,我们代码的核心就是如何实现判断B数组中是否已经有了这个字符。我们可以为此写一个函数,代码如下:
//用于检查是否有重复字符,有返回1,无返回0
int Check(char *B, int len, char e){
int i=0;
while(i < len){
if(B[i] == e)
return 1;
i++;
}
return 0;
}
函数传入了三个参数,char* B:字符类的字符指向数组B,len:数组B的长度,让我们知道遍历数组B的结束条件。char e:数组A中任意一个字符;通过遍历比较的方式来判断重复,接下来,函数的主题代码如下:
//主函数
int main(){
char A[100],B[100];
int i,len=0;
printf("请输入一串字符:\n");
gets(A);
for(i = 0; i < strlen(A); i++){
if(Check(B,len,A[i]) == 0){ //靠上文提到的Check函数判断B数组是否有这个字符,如果没有
//则进行如下操作
//将该字符添加到B数组中,长度加1
B[len] = A[i];
len++;
}
}
printf("清除多余字符的字符串如下:\n");
puts(B);
return 0;
}
完整代码如下:
#include <stdio.h>
#include <string.h>
//用于检查是否有重复字符,有返回1,无返回0
int Check(char *B, int len, char e){
int i = 0;
while( i< len){
if(B[i] == e)
return 1;
i++;
}
return 0;
}
//主函数
int main(){
char A[100],B[100];
int i,len = 0;
printf("请输入一串字符:\n");
gets(A);
for(i = 0;i < strlen(A);i++){
if(Check(B,len,A[i]) == 0){ //靠上文提到的Check函数判断B数组是否有这个字符,如果没有
//则进行如下操作
//将该字符添加到B数组中,长度加1
B[len] = A[i];
len++;
}
}
printf("清除多余字符的字符串如下:\n");
puts(B);
return 0;
}
运行结果如下:
算法复杂度分析
我们设数组A长度为n,数组B长度为m。n>=m。我们需要遍历数组A中的n个元素,在遍历数组A中每一个字符时,我们需要完整地遍历一遍数组B,需要len次。len的值一直在改变。我的总的操作次数为:1*a1+2*a2+3*a3+......+m*am (其中a1+a2+......+am=n-1,且其中每一项可以0) ,但我们不能用这样一个冗长的式子作为时间复杂度O,当n和m都趋向无穷时,上式就趋向于n*n.
这样我们得出结论,上述介绍算法的时间复杂度为O(n*n)