Z Z U L I 训练 : 数组和字符串专题 ZZULI训练: 数组和字符串专题 ZZULI训练:数组和字符串专题
- 部分多实例没写循环多次是因为在main里面循环了, 你们写的时候要加上
- 只提供大概思路和核心代码
- 建议多尝试一下c++, 并没有想象的那么难
7-1 个位数统计
- 可以开个数组来存一下每个数组出现的个数, c++的话直接用map就很方便 (数字很大, 要用字符串来存
void solve() {
map<char, int> mp;
string s; cin >> s;
for (auto c: s) mp[c] ++;
for (auto [c, cnt]: mp) {
printf("%c:%d\n", c, cnt);
}
}
7-2 检查密码
- 模拟一下题目的要求就可以了
- 注意数据中可能会有空格, cin和scanf都会读取错误, 换成gets或者getline就行
- 注意使用gets和getline要先把前面读的数据个数T后面的回车吃掉 (我已经在main中处理, 所以代码里没有体现这一点
- getchar(), cin.get()等等等都可以吃掉回车, 凭个人喜好选择即可
void print(int x) { // 把输出写成外函数, 看起来清楚一点
if (x == 0) cout << "Your password is wan mei.\n";
if (x == 1) cout << "Your password is tai duan le.\n";
if (x == 2) cout << "Your password is tai luan le.\n";
if (x == 3) cout << "Your password needs shu zi.\n";
if (x == 4) cout << "Your password needs zi mu.\n";
}
void solve() {
string s;
getline(cin, s);
if (s.size() < 6) {
print(1);
return;
}
int nums = 0, alp = 0; // 统计数字和字母的个数
for (auto c: s) {
if (c == '.') continue; // '.'特判
if (isdigit(c)) nums ++;
else if (isalpha(c)) alp ++;
else { // 出现非法字符
print(2);
return;
}
}
// 题目保证不会出现数字和字母都不存在的情况
if (!nums) print(3);
else if (!alp) print(4);
else print(0);
}
7-3 整数进制转换
- 进制转化, 没啥好说的, 记住如何实现就行
int n, base;
void solve() {
cin >> n >> base;
vector<int> ne;
while (n) {
ne.push_back(n % base);
n /= base;
}
reverse(ne.begin(), ne.end()); // 由于储存是逆向的, 需要反转
for (auto x: ne) cout << x;
cout << '\n'; // 题目要求末尾输出换行
}
7-4 求多少对相反数
- 和第一题实现差不多, 记录一下每个数是否出现, 数组, map, set都可以实现
void solve() {
map<int, int> mp;
cin >> n;
for (int i = 0; i < n; i ++) {
int x; cin >> x;
mp[x] ++;
if (mp[-x]) m ++; // 如果他的相反数存在, 那么答案 + 1
}
cout << m;
}
7-5 密码报错
- 把每一位都转化成小写(或者大写), 然后记录不相同的字母个数即可
void solve() {
string s, t;
cin >> s >> t;
int cnt = 0;
for (int i = 0; i < s.size(); i ++)
if (tolower(s[i]) != tolower(t[i]))
cnt ++;
cout << cnt;
}
7-6 合并数组
- 很适合用set的题
- set的性质: 自动排序, 只会存储下来不同的数字.
- 我们把两个数组中的元素全部存入一个set, set里面的元素就是答案辣
- 当然朴素方法也可以过, 但这里不再提供(相信你看了set的做法就会嫌弃朴素做法了
void solve() {
set<int> st;
int x;
while (cin >> x, x) st.insert(x); // 输入小技巧, 当输入的 x 是 0 时, 停止这次输入
while (cin >> x, x) st.insert(x);
for (auto x: st) cout << x << " ";
}
7-7 集合减法
- 没错, set还可以做, 记录第一个数组中的数字, 在输入第二个数组的时候判断该数字是否在set中, 如果存在就删去该数字
- 记得特判空的情况
void solve() {
cin >> n >> m;
set<int> st;
while (n --) {
int x; cin >> x;
st.insert(x);
}
while (m --) {
int x; cin >> x;
if (st.count(x)) st.erase(x);
}
for (auto x: st) cout << x << " ";
if (st.empty()) cout << 0;
}
7-8 十六进制数转换成相应的十进制数
- 又又是进制转化
- 特判负数即可
int base = 16;
int calc(string s) {
int res = 0;
for (auto c: s) {
if (isdigit(c)) res = res * base + c - '0';
else res = res * base + c - 'A' + 10; // 计算技巧, 快学一下吧
}
return res;
}
void solve() {
string s;
while (cin >> s) {
if (s[0] != '-') cout << calc(s) << "\n";
else cout << -calc(s.substr(1)) << "\n";
}
}
7-9 十进制整数转换成R进制数
- 又又又是进制转化
- 我的写法需要特判 0, 剩下的只需要处理输出即可
int n, base;
void solve() {
cin >> n >> base;
if (n < 0) return;
else if (n == 0) {
cout << 0;
return;
}
vector<int> ne;
while (n) {
ne.push_back(n % base);
n /= base;
}
reverse(ne.begin(), ne.end());
for (auto x: ne) {
if (x < 9) cout << x;
else cout << (char)(x - 10 + 'A'); // 转换成对应的字母
}
}
7-10 sdut-字符串排序
- 小知识, 字符串也可以用sort
- 记得处理最后一位的空格
void solve() {
vector<string> v;
string s;
while (cin >> s) v.push_back(s);
sort(v.begin(), v.end());
int n = v.size();
for (int i = 0; i < n - 1; i ++)
cout << v[i] << " ";
cout << v.back(); // 可以获取vector的最后一个元素
}