возвращение str против str.substr (0, str.size ()) дает мне различные выходные данные в leetcode - PullRequest
0 голосов
/ 31 января 2020

Я только что решил https://leetcode.com/problems/push-dominoes/.

Мой код

class Solution {
public:

    string pushDominoes(string dominoes) {
        string res(dominoes.size(), ' ');
        dominoes = 'L' + dominoes + 'R';

        int l = 0;
        for(int r = 1; r < dominoes.size(); r++)
        {
            if(dominoes[r] != '.')
            {
                //check which case we have [L...R], [R....L] [L.....L]  [R...R]
                if(l != 0) res[l-1] = dominoes[l]; 
                if(r != dominoes.size() - 1) res[r-1] = dominoes[r];

                if(dominoes[l] == dominoes[r])
                {
                    for(int i = l; i <= r; i++) 
                        if(i > 0) res[i-1] = dominoes[r];
                }
                else if(dominoes[l] == 'L' && dominoes[r] == 'R')
                    for(int i = l+1; i < r; i++) res[i-1] = '.';
                else if(dominoes[l] == 'R' && dominoes[r] == 'L')
                {
                    if((l+r)%2 == 0) 
                    {
                        auto mid = (l+r)/2;
                        res[mid-1] = '.';
                        for(int i = l+1; i < mid; i++) res[i-1] = 'R';
                        for(int i = mid+1; i < r; i++) res[i-1] = 'L';
                    }
                    else
                    {
                        auto mid = (l+r)/2;
                        for(int i = l+1; i <= mid; i++) res[i-1] = 'R';
                        for(int i = mid+1; i < r; i++) res[i-1] = 'L';
                    }
                }

                l = r;
            }
        }

        return res;
        // return res.substr(0, res.size());
    }
};

int main( ) 
{ 
   Solution soln;

   cout << soln.pushDominoes(".L.R.") << endl;
}

Для одного из тестовых случаев, где вводом является ".LR" leetcode утверждает, что мой вывод "LL.RRRLLRRLL ..", когда я использую return res. Ответ должен быть "LL.RR". Но я распечатал res, и это действительно "LL.RR" и размер 5.

Если я изменю свой код, чтобы вернуть return res.substr(0, res.size()) вместо return res, я получу правильное решение. Я озадачен тем, почему это происходит, когда эти 2 оператора возврата должны быть идентичными?

Я также портировал код и скомпилировал его на своем компьютере, и я получил правильное решение. Это заставляет меня задуматься, есть ли какие-то различия в том, как обрабатывается мой код между различными компиляторами C ++, или у Leetcode могут быть некоторые проблемы для этой конкретной проблемы. Любой совет?

1 Ответ

1 голос
/ 31 января 2020
string res(dominoes.size(), ' ');

Устанавливает размер res равным dominoes, и этот размер никогда не изменяется. res никогда не может быть больше, чем dominoes. При вводе ".LR" длина dominoes равна 5. res имеет длину 5.

dominoes = 'L' + dominoes + 'R';

Изменяет размер dominoes на 7.

for (int r = 1; r < dominoes.size(); r++)

повторяет r с 1 до 6.

В сторону: когда я вижу <= в for l oop, я останавливаюсь для более длинного взгляда. Это неправильно гораздо чаще, чем это правильно.

В этом случае кажется, что это только своего рода ошибка, позволяющая

for (int i = l; i <= r; i++)
    if (i > 0) res[i - 1] = dominoes[r];

повторять i с l до r. Поскольку r может быть 6, i может быть 6. Это означает, что

    if (6 > 0) res[6 - 1] = dominoes[6];

возможно. Это разрешает до

    res[5] = dominoes[6];

и res[5] недопустимо. Запись в него вызывает неопределенное поведение, и в этом случае, похоже, он перезаписывает нулевой терминатор строки c в стиле, поддерживающей string.

Еще одно замечание: избегайте использования l в качестве имени переменной. Это выглядит слишком похоже на 1 и приводит к ошибкам или неправильному чтению кода.

Чтобы исправить, вы можете расширить лог c из if (i > 0) в if (i > 0 && i-1 < res.size()), чтобы отфильтровать эту проблему, но вам лучше переделать или заменить алгоритм, чтобы вы никогда не оказались в такой ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...