关于 C++ 中的字符串流

About stringstreams in C++

在学习面试题的时候,在网上看到了这段代码:

class Solution {
public:
    string complexNumberMultiply(string a, string b) {

        //I initially did it using substring (searching for "+" etc.)
        //But it is super easy using stringstreams

        stringstream aa(a), bb(b), ans;
        int ra, rb, ia, ib;
        char buff;
        aa>>ra>>buff>>ia>>buff;
        bb>>rb>>buff>>ib>>buff;

        ans<<ra*rb-ia*ib<<"+"<<ra*ib+rb*ia<<"i";
        return ans.str();
    }
};

此代码段将两个输入字符串相乘,表示 a+bi 形式的复数。因此,如果输入为 1+1i1+1i,则此代码生成的输出为 0+2i(因为 i^2=-1)。

我明白为什么使用字符串流 aabb 以及它们是如何工作的;但我不明白 char buff 的作用。考虑以下语句:

aa>>ra>>buff>>ia>>buff;

这里,从stringstream aa我们首先读取有理部分ra(然后buff是加号“+”?),然后是虚部ia,然后再次 buff(可能是 \n?)。我的理解正确吗?但是,如果我删除缓冲区,它对 1+2i 这样的输入工作正常,但在虚部为负的情况下失败,例如 1+-2i(是的,不是 1-2i)。

如果我的理解正确,请告诉我。谢谢!

你几乎是正确的。当你有一个像 1+1i 这样的字符串时,你有两个有效的整数和两个有效的字符。所以 aa>>ra 将第一个整数读入 ra,留下 +1i。然后 >>buff 将字符 (+) 读入 buff,在流中留下 1i。然后 >>ia 读取下一个整数并在流中留下 i 。然后 >>buff 消耗流中剩余的 i

通常在做这样的事情时我喜欢使用更具描述性的变量名。我喜欢使用 eater 很多,因为它暗示我只是在吃掉输入(扔掉它)。如果我知道输入的内容,那么更具描述性的名称就更好了,例如 sign/operator/imaginary_part.

是的,你的理解是正确的。 operator >> 对于每个输入流(std::istream 的祖先)是通用的,它使用 std::num_get::get 表示整数。

根据阶段 2 逻辑和正虚部 aa >> ra >> rb 将 运行 像这样:

2 -> accumulated to storage "2" 
     (because 2 matches one of "0123456789abcdefxABCDEFX+-")
+ -> ignored, because "2+" is not valid integer for scanf, so first
     operator >> terminates here
+ -> accumulated to storage "+"
3 -> accumulated to storage "+3"
i -> ignored, because "+3i" is not a valid integer, so we 
     can scan "+3" as integer 3 and put it to rb

第二个整数的负虚部被破坏:

+ -> accumulated to storage "+"
- -> "+-" is not a valid scanf, so we should terminate second 
     operator >> while putting 0 to ra because "+" is also is not 
     an integer

因此,通过添加单个字符的显式读取,您可以在第二次 operator >> 中读取“+”,并且可以在第三次调用 operator >>[=19 时正确读取“3”或“-3” =]