题意:
把读入的字符串 s1<s2>s3<s4>s5 按 <、> 拆分成5段, 然后按 s1s2s3s4s5 输出第一个结果(即去掉 <、>), 把 s4s3s2s5 替换掉第二行中的 ... 输出第二个结果.
思路:
1. 把读入的字符串按 <、> 拆分成5段, 然后按需要组装进行输出.
要点:
1. cin 与 getline 混合用会有问题,cin 不会吃掉空白字符,getline 会吃掉空白字符, 所以 cin 完了应该接一个 cin.ignore(), 保证后面的 getline 能正确读取.
2. 字符串的替换, 应使用 string 中的 replace, 不要直接用 <algorithm> 中的 replace, 因为 <algorithm> 中的 replace 不会改变空间大小, 所以如果进行替换的字符串长度不一样, 就会导致异常.
3. 使用 string 的 substr 来提取子字符串.
题目:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=96&page=show_problem&problem=1302
代码:
# include <iostream> # include <string> # include <cstdio> # include <cstring> # include <vector> # include <algorithm> using namespace std; // 用 string 中的 replace, 不要直接用 <algorithm> 中的 replace // cin 与 getline 混合用会有问题,cin 不会吃掉空白字符,getline 会吃掉空白字符 // 所以 cin 完了应该接一个 cin.ignore(), 保证后面的 getline 能正确读取 // 将 src 中的所有的 oldStr 替换成 newStr string replaceAll(string src, const string oldStr, const string newStr) { size_t found; int len = oldStr.size(); while( (found = src.find(oldStr)) != string::npos ){ src.replace(found, len, newStr); } return src; } // 将 s1<s2>s3<s4>s5 根据 < 和 > 拆成 5 段 vector<string> splitTo5(string line1){ vector<string> vt; size_t left; size_t right; // 这里如果用 iterator 怎么实现? // 第 1 段 left = line1.find("<"); vt.push_back(line1.substr(0, left-1)); // 第 2 段 right = line1.find(">", left); vt.push_back(line1.substr(left+1, right-left-1)); // 第 3 段 left = line1.find("<", right); vt.push_back(line1.substr(right+1, left-right-1)); // 第 4 段 right = line1.find(">", left); vt.push_back(line1.substr(left+1, right-left-1)); // 第 5 段 vt.push_back(line1.substr(right+1)); return vt; } int main(int argc, char const *argv[]) { #ifndef ONLINE_JUDGE freopen ("10361_i.txt", "r", stdin); freopen ("10361_o.txt", "w", stdout); #endif int linePair = 0; cin >> linePair; cin.ignore(); // 必须有这行,否则下面 getline 会读到空行 for(int i=0; i<linePair; i++){ string line1; string line2; getline(cin, line1); getline(cin, line2); vector<string> vt5 = splitTo5(line1); string newThreeDot = vt5[3] + vt5[2] + vt5[1] + vt5[4]; // line1 的 < > 都要去掉 // 这里可以直接输出 vt5[0] + vt5[1] + vt5[2] + vt5[3] + vt5[4] 的, 当时没想到, 算了... line1 = replaceAll(line1, "<", ""); line1 = replaceAll(line1, ">", ""); cout << line1 << endl; // 这样写 replace 是不行的,因为 algorithm 中的 replace 不能改变空间的大小 // replace(line1.begin(), line1.end(), "<", ""); // replace(line1.begin(), line1.end(), ">", ""); line2 = replaceAll(line2, "...", newThreeDot); cout << line2 << endl; } return 0; }
环境:C++ 4.5.3 - GNU C++ Compiler with options: -lm -lcrypt -O2 -pipe -DONLINE_JUDGE