vector 的用法
今天做的题目
写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字符,然后输出输入字符串中该字符的出现次数。(不区分大小写字母),数据范围:
刚开始是用的把字符串长度写死的方法,但是这么写太浪费内存了,感觉不够优雅,然后查了查有没有更优雅的方式来解决;
1. 动态数组
最开始的写法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <array> #include <iostream> using namespace std;
int main() { std::array<string, 1000> Buffer; char flag; int cnt = 0,B_cnt = 0; int i = 0; while (cin >> Buffer[i]) { i++; } for(B_cnt = i - 1; i > 0; i--) { for(int j = 0; j < Buffer[i - 1].length(); j++) { if(Buffer[B_cnt][0] >= 65 && Buffer[B_cnt][0] <= 90) { if(Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] + 32 == Buffer[i - 1][j]) cnt++; } else if(Buffer[B_cnt][0] >= 97 && Buffer[B_cnt][0] <= 122) { if(Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] - 32 == Buffer[i - 1][j]) cnt++; } else if(Buffer[B_cnt][0] == Buffer[i - 1][j]) cnt++;
} } if(cnt > 0) cnt--; cout << cnt << endl; }
|
但是这么写发现如果输入的字符串中没有空格的话就等于浪费了 998 个字符串的空间,所以首先想到的是能不能开辟一块动态数组,
于是使用了 new 的方式来用动态数组进行内存分配,其格式为
1 2 3 4 5
| int size = 1000; int* Dynamic_Arr = new int[size]; int* Dynamic_Arr2 = new int[size](); string* Dynamic_Arr3 = new string[size]{"aa", "bb","cc", "dd", string(2, 'e') }; delete [ ] Dynamic_Arr;
|
释放一个动态数组时,或者说是指向数组的指针时,空括号是必须的。它告诉编译器,指针指向一个数组的第一个元素;使用动态数组时,一定要记得显式的释放内存,否则很容易出错。
这样这道题的版本就变成了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| #include <iostream> using namespace std;
void main() { int size = 1000; string* Buffer = new string[size]();
char flag; int cnt = 0, B_cnt = 0; int i = 0; while (cin >> Buffer[i]) { i++; } for (B_cnt = i - 1; i > 0; i--) { for (int j = 0; j < Buffer[i - 1].length(); j++) { if (Buffer[B_cnt][0] >= 65 && Buffer[B_cnt][0] <= 90) { if (Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] + 32 == Buffer[i - 1][j]) cnt++; } else if (Buffer[B_cnt][0] >= 97 && Buffer[B_cnt][0] <= 122) { if (Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] - 32 == Buffer[i - 1][j]) cnt++; } else if (Buffer[B_cnt][0] == Buffer[i - 1][j]) cnt++;
} } if (cnt > 0) cnt--; cout << cnt << endl; delete[] Buffer; }
|
但是尽管是动态的,但实质上还是在未知长度的情况下不能进行最大程度的空间利用,
有没有一种办法是,每读一次字符串就写入,如果后续还有再进行读入呢;
2. STL vector
此时就想到了 vector ,一种可以自动改变数组长度的数组,
2.1 vector 的定义
vector 是向量类型,是 STL 中的一种重要的容器,使用时应当包含头文件 <vector>
1 2
| #include <vector> using namespace std;
|
其定义格式为:
类型名可以是int、double、char、struct,也可以是STL容器;
常见的初始化方式有:
1 2 3 4 5 6 7 8 9 10
| vector<int> a(10);
vector<int> a(10,1);
vector<int> a(b);
vector<int> a(b.begin(),b.begin+3);
int b[7]={1,2,3,4,5,9,8}; vector<int> a(b,b+7);
|
2.2 vector 容器内元素的访问
主要有两种访问方式:
类似于直接使用数组的下标访问其内部元素;
迭代器(iterator)可以理解为指针:
1
| vector<类型名>::iterator 变量名;
|
2.3 vector 常用函数
在 vector 的最后一个向量后插入一个元素,其值为括号内的元素;因此要处理不定长数组进行内存分配的问题,只需要 push_back() 就好了;
删除 vector 的最后一个元素;
返回 vector 中元素的个数,时间复杂度为O(1);
用于清空 vector 中的所有元素,时间复杂度为O(N) ,其中N为 vector 中元素的个数;
返回 vector 的最后一个元素;
返回 vector 的第一个元素;
返回 vector 在内存中总共可以容纳的元素个数;
将 vector 中的元素和括号中的元素进行整体性交换;可用于与空 vector 交换以释放内存;
1 2 3 4 5
| insert()
a.insert(a.begin()+1,5); a.insert(a.begin()+1,3,5); a.insert(a.begin()+1,b+3,b+6);
|
根据指定位置在 vector 中插入元素;
1 2 3
| erase()
erase(a.begin()+1,a.begin()+3);
|
删除指定位置的元素;
其他常用函数举例:
1 2 3 4 5 6 7 8 9 10 11
| a.assign(b.begin(), b.begin()+3); a.assign(4,2);
a[i];
a.resize(10); a.resize(10,2);
a.reserve(100);
a==b;
|
3. 总结
最终的用 vector 来实现的代码如下,最终三者的运行结果是一致的,但是第三种写法能够容纳更长的输入字符串,其程序鲁棒性也更强(总的来说感觉更优雅一点…)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| #include <vector> #include <iostream> using namespace std;
void main() { std::vector<string> Buffer; string tmp; int cnt = 0, B_cnt = 0; int i = 0; while (cin >> tmp) { Buffer.push_back(tmp); i++; } for (B_cnt = i - 1; i > 0; i--) { for (int j = 0; j < Buffer[i - 1].length(); j++) { if (Buffer[B_cnt][0] >= 65 && Buffer[B_cnt][0] <= 90) { if (Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] + 32 == Buffer[i - 1][j]) cnt++; } else if (Buffer[B_cnt][0] >= 97 && Buffer[B_cnt][0] <= 122) { if (Buffer[B_cnt][0] == Buffer[i - 1][j] || Buffer[B_cnt][0] - 32 == Buffer[i - 1][j]) cnt++; } else if (Buffer[B_cnt][0] == Buffer[i - 1][j]) cnt++;
} } if (cnt > 0) cnt--; cout << cnt << endl; std::vector<string>().swap(Buffer); }
|
参考网页:
- C++ vector的用法(整理)-CSDN博客
- 【C++】标准模板库(STL):超快入门!算法竞赛必看! - 知乎 (zhihu.com)
- 【C++】细说C++中的数组之动态数组_c++动态数组-CSDN博客