PAT乙级1009题是一道经典的字符串处理题目,要求将输入的句子按单词逆序输出。这道题看似简单,但涉及多个C++字符串处理的关键知识点,非常适合用来训练基础编程能力。
题目要求:给定一句英语句子,要求将句中所有单词的顺序颠倒输出。例如输入"Hello World Here I Come",输出应为"Come I Here World Hello"。
这道题的核心在于如何高效地分割字符串并存储单词。常见的解决方案有:
原代码采用的是类似双指针的方法,通过记录空格位置来截取子字符串。这种方法虽然不如使用栈直观,但在空间利用上更为高效。
原代码的主要逻辑分为两部分:
这种实现方式避免了使用额外数据结构(如栈),直接在原字符串上操作,体现了对字符串操作的深入理解。
cpp复制vector<string> v;
string s;
getline(cin, s);
s += ' ';
int num1 = 0, num2 = -1, num3 = 0, flag = 0;
for(int i = 0; i < s.size(); i ++) {
if(s[i] == ' ') {
num3 = i;
num1 = num2 + 1;
num2 = num3;
v.push_back(s.substr(num1, num2 - num1));
}
}
这段代码有几个值得注意的技术点:
s += ' '是为了统一处理最后一个单词,避免特殊判断提示:在实际编程竞赛中,这种精确的字符串操作很常见,需要熟练掌握substr的参数含义。
cpp复制for(int i = v.size() - 1; i >= 0; i --) {
if(flag == 1) cout << " ";
flag = 1;
cout << v[i];
}
这段代码展示了经典的逆序输出模式:
i = v.size() - 1开始递减cpp复制stringstream ss(s);
string word;
while(ss >> word) {
v.push_back(word);
}
这种方法更简洁,且自动处理连续空格等情况。
cpp复制reverse(v.begin(), v.end());
for(auto &word : v) {
cout << word << " ";
}
更符合C++的现代编程风格。
这类字符串处理题目最容易在边界条件上出错:
cpp复制cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;
在复杂字符串操作中,打印指针位置能快速定位问题。
cpp复制assert(num1 <= num2 && num2 <= num3);
确保指针关系的正确性。
在实际编程中,我发现这类字符串处理题目最考验基本功的扎实程度。看似简单的需求,要实现得既正确又高效并不容易。建议初学者多练习这类题目,培养对字符串操作的敏感度。