(一)暴力做法/朴素做法/不加优化的做法
S1=“They are students.”
S2=“aeiou”
删除S1中包含S2中字母的部分
输入一个包含空格的字符串,不能用cin,可以用getline(cin, s1);
依次遍历每个字符串
从前往后遍历S1中每一个字符,判断是否在S2中出现过
若在S2中出现过,就不加
若没出现过,就加
双重循环
for S1
for S2
两个字符串最多10^4个长度
算法时间复杂度,平方级:10^8
(二)时间限制与时间复杂度关系
若时间限制是1s, 则时间复杂度应该在10^7 ~ 10^8
若时间限制是0.1s,则时间复杂度应该在10^6 ~ 10^7
所以直接这么做的话,很可能会超时
暴力算法会超时间,需要一些优化
时间复杂度超过时间限制 Time Limit Exceeded
闫式暴力算法
#include <iostream>
using namespace std;
string s1,s2;
bool check_exists(char c)
{
for (auto a : s2)
if(a == c)
return true;
return false;
}
int main()
{
getline(cin, s1);
getline(cin, s2);
string res;//答案result存储s1剔除结果后的字符
for(auto c : s1)
if( !check_exists(c))//如果没有出现过
res += c;
cout << res << endl;
return 0;
}
(三)优化:
主函数中无法优化
所以只能优化check_exists()的O(n)
函数的作用:判断某一个字符是不是在某字符串中出现过
=>判断某个元素是否在某个集合中出现过
=>哈希表
可以支持:增删改查 每个操作的平均时间复杂度为O(1)
C++中提供 哈希表 容器
unordered_set<char> hash;
是有序的,基于平衡树实现O(logn)
#include<set>维护一个变量
#include<map>维护两个变量,可以把一个变量映射到另一个变量中,int形和数组类似
不允许有重复元素
set<int> a;//维护一个有序集合
map<int,int> b;//映射
b[x]=y;
允许有重复元素
multiset<int> c;
multiset<int,int> d;
是无序的,基于哈希表实现O(1)
#include<unordered_set>
#include<unordered_map>
不允许有重复元素
unordered_set<int> e;//维护一个有序集合
unordered_map<int,int> f;//映射
b[x]=y;
允许有重复元素
unordered_multiset<int> g;
unordered_multiset<int,int> h;
闫式优美题解(哈希表优化后)
#include <iostream>
#include <unordered_set>
using namespace std;
string s1,s2;
int main()
{
getline(cin, s1);
getline(cin, s2);
unordered_set<char> hash;//定义哈希表 想哈希一个字符所以是char类型
for (auto c : s2) hash.insert(c);//将s2中的字符插入哈希表 需要先插入到哈希表中,按此能对他进行判断
string res;//答案result存储s1剔除结果后的字符
for(auto c : s1)
if( !hash.count(c))//统计哈希表中字符c出现的次数,int型
//刚才的check函数是O(N),此处应用了哈希表是O(1)
res += c;
cout << res << endl;
return 0;
}