Living-Dream 系列笔记 第2期

本期主要讲解 vectormap 两个 STL 容器。

知识点:

首先,引入两种数组的区别:

  • 静态数组,指提前声明需要多少内存的数组,是连续的;

  • 而动态数组则是在插入元素时临时指定存储空间,不要求连续。

STL vector 是一个动态数组,下标默认从 \(0\) 开始。它支持的操作如下:

  • 定义:一维 vector<TYPE> NAME,二维 vector<TYPE> NAME[SIZE],一般不定义 vectorvector

  • 插入:NAME.push_back(VAL)

  • 长度:NAME.size()

  • 访问:NAME[POS]。(注意不是 \(O(1)\)

STL map 则是一个有序键值对,在数学上被称为映射,其中的键(\(key\))唯一,而值(\(value\))不唯一。同时 map 具有去重的性质。

它支持的操作如下:

  • 定义:map<TYPE,TYPE> NAME

  • 赋值:map[KEY]=VAL

  • 长度:NAME.size()

  • 统计:NAME.count(VAL)

(更多 vectormap 的操作请访问 zh.cppreference.com

例题

T1

维护一个 map,记录每个字符串的编号,最后输出长度即可。

#include<bits/stdc++.h>
using namespace std;
int n;
map<string,int> m;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
string s; cin>>s;
m[s]=i;
}
cout<<m.size();
return 0;
}

T2

题目有点绕,其实就是要你求出字符串 \(s\) 中最短的子串 \(t\) 的长度。因为 \(n\) 很小,所以考虑 \(O(n^3)\) 的枚举。

循环 \(1 \sim n\) 枚举 \(t\) 的长度 \(k\),同时循环 \(1 \sim n-k+1\) 枚举 \(t\) 的起点,利用 substr \(O(n)\) 地求出 \(t\),若 \(t\) 自始至终只出现了一次,则当前的 \(k\) 即为答案。

#include<bits/stdc++.h>
using namespace std;
int n,ans;
string s;
map<string,int> m;
int main(){
cin>>n>>s;
for(int i=1;i<=n;i++){
bool f=0;
for(int j=0;i+j-1<n;j++){
string t=s.substr(j,i);
if(m[t]!=0){
f=1;
break;
}
m[t]++;
}
if(!f){
cout<<i<<'\n'; break;
}
}
return 0;
}

T4

维护一个 map,对于每个字符串,若它在 map 中未出现,则输出 YES,反之输出 NO,同时将其插入 map 中。

我用的是 set,更为简便。

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
set<string> x;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>s,cout<<(x.count(s)?"YES\n":"NO\n"),x.insert(s);
return 0;
}

习题

T5

开个结构体,记录名称 \(s\) / 地址 \(ip\) / (针对命令的)指向的服务器地址 \(p\)

遍历每条命令,循环查找与其对应的服务器,将服务器名称存入 \(p\) 中。

最后按格式输出每条命令的 \(s\)\(ip\)\(p\)

#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
string name,p,ip;
}a[2031];
int main(){
cin>>n>>m;
for(int i=1;i<=n+m;i++)
cin>>a[i].name>>a[i].ip;
for(int i=n+1;i<=n+m;i++){
for(int j=1;j<=n;j++){
string t=a[j].ip+";";
if(t==a[i].ip)
a[i].p=a[j].name;
}
}
for(int i=n+1;i<=n+m;i++)
cout<<a[i].name<<" "<<a[i].ip<<" #"<<a[i].p<<"\n";
return 0;
}

T6

我们令原字符串为 \(s\)

  • 对于操作 1,令新字符串为 \(t\),则输出 \(s+t\)

  • 对于操作 2,令 \(s \gets s.\text{substr}(a,b)\),并输出 \(s\)

  • 对于操作 3,令新字符串为 \(t\),则 \(s.\text{insert}(a,b)\),并输出 \(s\)

  • 对于操作 4,令新字符串为 \(t\),若 \(s.\text{find}(t) \neq \text{string::npos}\),则输出 \(s.\text{find}(t)\),否则输出 \(-1\)

#include<bits/stdc++.h>
using namespace std;
int q,op,a,b;
string f,s;
int main(){
cin>>q>>f;
while(q--){
cin>>op;
if(op==1)
cin>>s,f+=s,cout<<f<<'\n';
else if(op==2)
cin>>a>>b,f=f.substr(a,b),cout<<f<<'\n';
else if(op==3)
cin>>a>>s,f.insert(a,s),cout<<f<<'\n';
else{
cin>>s;
if(f.find(s)!=string::npos) cout<<f.find(s)<<'\n';
else cout<<"-1\n";
}
}
return 0;
}

T7

运用 map 存储每一个数,若它是第一次出现则输出并标记。

unordered_map 更佳。

#include<bits/stdc++.h>
using namespace std;
int T;
unordered_map<int,bool> ump;
int main(){
ios::sync_with_stdio(0); cin.tie(nullptr);
cin>>T;
while(T--){
ump.clear();
int n; cin>>n;
for(int i=1;i<=n;i++){
int x; cin>>x;
if(ump[x]==false){ cout<<x<<' '; ump[x]=true; }
}
cout<<'\n';
}
return 0;
}
posted @   _XOFqwq  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示