Строковое стирание (), дающее ядро ​​сброшенным - PullRequest
0 голосов
/ 01 декабря 2018

Я делаю ката на codewars, и мне нужно что-то вроде этого:Когда буква в строке встречается два раза - удалите оба.

Я сделал что-то вроде этого:

    std::string str2 = str;

for(int i=0;i<str2.size();i++){
    for(int j=0;j<str2.size();j++){

        if(std::tolower(str2[i]) == std::tolower(str2[j]) && j != i){
            n++;
            str2.erase(str2.begin() + i);
            str2.erase(str2.begin() + j);

            i--;
            j--;
        }

    }
}

И получил дамп ядра (это вызвано str2.erase(str2.begin() + i);).Я знаю, что это где-то моя ошибка с памятью, но можете ли вы сказать мне, что не так с этим?Я проанализировал и не увидел там ничего плохого.

Ответы [ 2 ]

0 голосов
/ 01 декабря 2018

Во-первых, мы можем наблюдать, что когда происходит стирание, у нас всегда будет i<j.

Задача 1

Теперь, если вы удалите первый символ, а затем второй, вы 'стрельба по движущейся цели: вам нужно настроить новое положение второго символа после удаления первого:

        str2.erase(str2.begin() + i);
        str2.erase(str2.begin() + j-1);  // because former j c[j] is now c[j-1]

Другой вариант, который также подходит, - сначала удалить второй символ (нене изменяйте положение первого):

        str2.erase(str2.begin() + j);   // because j> i it has no impact on i
        str2.erase(str2.begin() + i);

Оптимизация 1

Не связано, но мы также можем использовать наш вычет на i<j для оптимизации или зацикливания и сохранения значительногоколичество бесполезных сравнений:

for(int i=0;i<str2.size();i++) {
    for(int j=i+1;j<str2.size();j++) {
    ...
    }
}

Оптимизация 2

Другая проблема заключается в том, что вы выполняете i-- во внутреннем цикле, когда i не увеличивается.Это будет иметь два последствия, вы будете повторять сравнения, которые вы уже делаете.Так что просто удалите этот декремент и перезапустите с j=i+1.

Онлайн демо .

Задача 2 (оставлено в качестве упражнения)

Ваш алгоритм удаляет только пары букв.Таким образом, если у вас есть более двух вхождений буквы, только два первых будут удалены.Поэтому вам нужно пересмотреть свой алгоритм (обратите внимание, чтобы не стереть несколько раз при первом появлении ;-))

0 голосов
/ 01 декабря 2018

Вы стираете два символа из str2.Если i меньше, чем j, это может привести к тому, что второе стирание получит доступ после конца строки (и даже если это не так, вы удалите неправильный символ).

...