01
收集字母
如果当前字符是小写字母,就把它接到 word 后面。也就是说,word 始终保存“当前还没处理完的单词”。
a -> word
b -> word
c -> word = abc
B3927 / String Simulation
这题本质上只做一件事:从左到右扫一遍文章。字母先装进小口袋,碰到标点就把口袋里的单词拿去查字典,再把标点原样输出。
UNK。
讲课时可以一直围绕这三步来板书,学生不容易乱。
如果当前字符是小写字母,就把它接到 word 后面。也就是说,word 始终保存“当前还没处理完的单词”。
只要遇到标点,说明前面的单词结束了。先拿 word 去字典里找翻译,输出后清空 word,再把标点自己输出。
字典最多只有 100 条,直接顺序查找就够了。如果从头到尾都没找到,就输出大写 UNK。
下面用题目的经典样例 abc.d.d.abc.abcd. 来看程序是怎么一步步翻译的。
还没开始
word空
点击“下一步”开始演示。
空
这里保留了信奥里更常见的写法:普通下标循环、数组存字典、顺序查找,不用 foreach,更容易跟着讲。
#include <bits/stdc++.h>
using namespace std;
string a[105], b[105];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i] >> b[i];
}
string s;
cin >> s;
s += ' '; // 哨兵,保证最后一个单词也会被处理
string word = "";
for (int i = 0; i < (int)s.size(); i++) {
char ch = s[i];
if ('a' <= ch && ch <= 'z') {
word += ch;
} else {
if (word != "") {
int pos = 0;
for (int j = 1; j <= n; j++) {
if (a[j] == word) {
pos = j;
break;
}
}
if (pos == 0) cout << "UNK";
else cout << b[pos];
word = "";
}
if (ch != ' ') {
cout << ch;
}
}
}
return 0;
}