C++机试输入输出处理
本文最后更新于 299 天前,其中的信息可能已经有所发展或是发生改变。

我在 25 保研高校夏令营机试中,被输入输出处理毒害不浅。不是不会做,而是花了大力气从提供的输入中解析出需要的数据,以及将得到的答案按照题目要求输出出来。

这次,真要把部分输入输出处理的方法整理出来。

1 stringstream

算法题输入输出主要有两种方式。第一种是 ACM 竞赛中提交完整的程序代码,输入输出分别在 stdinstdout 中;第二种如力扣的提交部分代码,输入输出分别在函数的参数和返回值中。

那么下述这种方式真的很难遇到:提交部分代码,输入以 string 字符串传入函数,输出以 string 字符串返回。代码框架如下:

string solve(string s) {
}

如果输入是一个长度为 $n$ 的数组,那么 s 组成方式为 n a1 a2 a3 ... an 。如果不会 stringstream ,只有将这个当一个 char 逐个字符解析了。如果输出是多个数字,你还需要想办法构造这样一个字符串。

stringstream 是一种流,可以操作输入输出,使用方法如下:

string solve(string s) {
  stringstream in(s); // use string s as input stream.

  int n;
  in >> n;

  vecotr<int> a(n);

  for (int &x: a) {
    in >> x;
  }

  stringstream out; // output stream.

  for (int x: a) {
    out << x << '\n';
  }

  return out.str(); // get string object from stringstream
}

2 输入处理

题目描述:我们的输入可能包含多个空格……

2.1 getline

问题来源,gets 是一个非安全函数,已经被弃用了。

getline 需要传入两个参数。第一个参数 is ,为输入流;第二个参数为 str ,为 string 类型变量。示例如下:

void solve() {
  string input_line;
  getline(cin, input_line); // the end character is '\0', not '\n'.
}

2.2 split

这种输入含多个空格的一般会提供分隔符。我们需要使用 string 类相关方法来实现:

  • find 方法:传递两个参数。第一个参数为需要查找的字符串 str ,第二个参数为查找的起始位置 pos (默认为 0 )。如果没有找到,返回 string::npos
  • substr 方法:传递两个参数。第一参数子串起始位置下表,第二个参数为子串结束位置的下标的下一位。
  • erease 方法:传递两个参数。第一参数需要删除子串起始位置迭代器,第二个参数为需要删除子串结束位置迭代器。

我们假设分隔符为 : 。首先需要找到 : 的位置,代码为 s.find(delimiter) ,在此位置之前就是我们需要的数据,可以使用 substr 方法获取,代码为 s.substr(0, s.find(delimiter)) 。如果有多个数据以该分隔符分离,代码实现如下:

std::string s = "scott>=tiger>=mushroom";
std::string delimiter = ">=";

size_t pos = 0;
std::string token;
while ((pos = s.find(delimiter)) != std::string::npos) {
    token = s.substr(0, pos);
    std::cout << token << std::endl;
    s.erase(0, pos + delimiter.length());
}
std::cout << s << std::endl;

2.3 trim

按照 2.2 节的方法获得数据之后,需要过滤首尾多余的空格。C++ 并不像 Java 等语言提供了该函数,我们需要自己使用 stringfind 方法以及 erase 方法实现。实现的代码如下:

inline void ltrim(std::string &s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
        return !std::isspace(ch);
    }));
}

inline void rtrim(std::string &s) {
    s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
        return !std::isspace(ch);
    }).base(), s.end());
}

inline void trim(std::string &s) {
  ltrim(s);
  rtrim(s);
}

参考资料

stringstream手册

C++流总结

getline手册

Parse (split) a string in C++ using string delimiter (standard C++)

string手册

How to trim a std::string?

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇