О струнных потоках в 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+1i а также 1+1i, то результат, сгенерированный этим кодом 0+2i (так как i^2=-1).

Я понимаю, почему струнные потоки aa а также bb были использованы и как они работают; но я не понимаю роли char buff, Рассмотрим утверждение:

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

Здесь из струнного потока aa мы сначала читаем рациональную часть ra (затем buff за плюс "+"?), то мнимая часть ia а затем buff еще раз (может быть, для \n?). Правильно ли мое понимание? Если я удаляю буферы, это работает нормально для входов, таких как 1+2i но терпит неудачу, где мнимая часть отрицательна, как 1+-2i (да не 1-2i).

Пожалуйста, дайте мне знать, если мое понимание верно. Спасибо!

2 ответа

Решение

Вы почти правы. Когда у вас есть строка, как 1+1i у вас есть два действительных целых числа и два действительных символа. Так aa>>ra читает первые целые числа в ra оставляя тебя с +1i, затем >>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

Таким образом, добавляя явное чтение одного символа, вы читаете "+" во 2-м operator >> и может читать "3" или "-3" правильно в 3-м вызове operator >>

Другие вопросы по тегам