算法-删除字符串中的公共字符
2017-08-15 18:15
218 查看
题目:
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入“They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
解题思路:
好未来那这道题做过笔试题目,首先最简单的思路就是两层循环遍历,下面将“They are students.”称为字符串1,将“aeiou”称为字符串2。每遍历到字符串2中的一个字符,就在字符串1中找到相同的字符,找到之后删除它,并将字符串1后面的字符整体向前移动1位。所以这个过程的时间复杂度是O(n^3),下面我们就可以考虑如何优化它了:
1.如何解决顺序存储结构中删除后整体移动的问题?
假设当前遍历到字符串2中的“a”,现在遍历字符串1,要求是是“a”的话就删除,那么这个要求换一个思路就是不是“a”就保留,在不申请新的空间的情况下,我们只需要把要保留的字符覆盖字符串中1原来的字符,要删除的字符不做覆盖,此时就需要有两个指针,一个在控制整体的遍历过程,一个记录要插入的位置:
可以看到,在遍历的过程中,如果没有出现要删除的字符的话,p1和p2一直在同步走(同步走的过程也是要覆盖的过程,一直在用p1的指向字符覆盖p2,只是他们指向相同,覆盖也就没有意义了),而出现了要删除的字符,p2会停下来,指示p1指向的字符要覆盖的位置,这样的话,我们就能避免每一次删除后的整体平移,这样的话时间复杂度还有O(n^2)。
2.如何避免两层遍历的嵌套?
O(n^2)的时间复杂度是由遍历两个字符串产生的,能否应用一些方法避免循环嵌套的问题,引入hash表。
两个遍历嵌套的过程无非是为了找到字符串2中的字符在字符串1中是否出现,那么如果我们对字符串1建立hash表,在遍历字符串2时就可以根据hash索引直接找到要删除的字符,这样的话时间复杂度就可以降到O(n),下面考虑字符串2中出现重复字符的情况,无所谓啊,反正都是要删了的。
所以我们就能对字符串2建立一个hash表了,hash函数选择:
hash表范围的选取:
a :97
A :65
z :122
Z :90
标点符号还在字母之前,所以hash范围选成256就足够了。
所以总的来说,我们用一个O(256)的空间复杂度,将时间复杂度从O(n^2)将为O(n),所以如果n很大的话,这个替换是值得的。
代码实现:
输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入“They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
解题思路:
好未来那这道题做过笔试题目,首先最简单的思路就是两层循环遍历,下面将“They are students.”称为字符串1,将“aeiou”称为字符串2。每遍历到字符串2中的一个字符,就在字符串1中找到相同的字符,找到之后删除它,并将字符串1后面的字符整体向前移动1位。所以这个过程的时间复杂度是O(n^3),下面我们就可以考虑如何优化它了:
1.如何解决顺序存储结构中删除后整体移动的问题?
假设当前遍历到字符串2中的“a”,现在遍历字符串1,要求是是“a”的话就删除,那么这个要求换一个思路就是不是“a”就保留,在不申请新的空间的情况下,我们只需要把要保留的字符覆盖字符串中1原来的字符,要删除的字符不做覆盖,此时就需要有两个指针,一个在控制整体的遍历过程,一个记录要插入的位置:
可以看到,在遍历的过程中,如果没有出现要删除的字符的话,p1和p2一直在同步走(同步走的过程也是要覆盖的过程,一直在用p1的指向字符覆盖p2,只是他们指向相同,覆盖也就没有意义了),而出现了要删除的字符,p2会停下来,指示p1指向的字符要覆盖的位置,这样的话,我们就能避免每一次删除后的整体平移,这样的话时间复杂度还有O(n^2)。
2.如何避免两层遍历的嵌套?
O(n^2)的时间复杂度是由遍历两个字符串产生的,能否应用一些方法避免循环嵌套的问题,引入hash表。
两个遍历嵌套的过程无非是为了找到字符串2中的字符在字符串1中是否出现,那么如果我们对字符串1建立hash表,在遍历字符串2时就可以根据hash索引直接找到要删除的字符,这样的话时间复杂度就可以降到O(n),下面考虑字符串2中出现重复字符的情况,无所谓啊,反正都是要删了的。
所以我们就能对字符串2建立一个hash表了,hash函数选择:
(int)arr2。在字符串2中出现的字符,在hash表中的值为1,未出现的字符表值为0。
hash表范围的选取:
a :97
A :65
z :122
Z :90
标点符号还在字母之前,所以hash范围选成256就足够了。
所以总的来说,我们用一个O(256)的空间复杂度,将时间复杂度从O(n^2)将为O(n),所以如果n很大的话,这个替换是值得的。
代码实现:
#include "iostream" using namespace std; void DeleteChar(char arr1[],char arr2[]); int main() { char str1[] = "They are students."; char str2[] = "aeiou"; cout<<str1<<endl; DeleteChar(str1,str2); cout<<str1<<endl; getchar(); return 0; } void DeleteChar(char *arr1,char *arr2) { if(arr1 == NULL && arr2 == NULL) return; //创建hash表 int hash_table[256] = { 0 }; char *p1 = arr1; char *p2 = arr2; int index =0; //遍历删除串 while(*p2 != '\0') { hash_table[(int)*p2] = 1; p2++; } //遍历待删除串 while (*p1 != '\0') { //该字符不需要删除 if( 0 == hash_table[(int)*p1] ) { arr1[index]= *p1; index++; } p1++; } arr1[index]='\0'; }
相关文章推荐
- 微软等数据结构+算法面试100题(29)--在字符串中删除特定的字符
- 删除字符串中重复的字符(算法)
- 【算法20】在字符串中删除特定的字符
- 【算法】从字符串中删除一系列字符
- [算法]删除字符串中重复的字符
- 算法习题63:字符串删除特定字符
- 每天一道算法题(7)——在字符串中删除特定的字符
- 每天一道算法题(7)——在字符串中删除特定的字符
- 程序员面试题精选100题(36)-在字符串中删除特定的字符[算法]
- 算法基础:删除字符串中出现次数最少的字符(Golang实现)
- 程序员面试题精选100题(36)-在字符串中删除特定的字符[算法]
- 微软等数据结构+算法面试100题(29)--在字符串中删除特定的字符
- 【算法20】在字符串中删除特定的字符
- [C/C++]_[初级]_[标准库之几种算法库函数的运用,如字符串查找(字符个数查找)、分隔、删除、替换、排序、字符交换位置、大小写转换等等]
- 每天一道算法题12 在字符串中删除特定的字符
- [算法] 定义一个函数,删除字符串中所有重复出现的字符。
- 算法题40 在字符串中删除特定的字符。
- 算法分析---删除字符串中出现次数最少的字符
- 面试题-在字符串中删除特定的字符[算法]
- [算法练习]字符.字符串删除,字符提前