JavaScript - сравнивает строки и удаляет первый символ из одной строки, пока они не станут равными - PullRequest
0 голосов
/ 07 мая 2019

Ссылка на CodeWars kata

Вам даны две строки. За один ход вы можете выбрать любой из них и удалить первый (т.е. самый левый) символ.

Например:

При применении перемещения к строке "where" в результате получается строка "here". Применяя перемещение к строке «a», результатом будет пустая строка «». Реализуйте функцию, которая вычисляет минимальное количество ходов, которые должны быть выполнены, чтобы сделать заданные строки равными.

Примечания:

Обе строки состоят из строчных латинских букв. Если строка уже пуста, вы больше не можете выполнять операции удаления.

Моя проблема в том, что я предполагаю, что вам нужно перебрать обе строки, чтобы продолжить сравнение, равны они или нет. Если они не равны, увеличьте счетчик и повторите цикл.

Но я не уверен, правильно ли я одновременно перебираю обе строки.

Является ли i < (s.length, t.length); правильным синтаксисом?

Вот что я пробовал:

function shiftLeft(s, t) {

    let sArray = s.split("");
    let tArray = t.split("");

    let counter = 0;

    for (let i = 0; i < Math.min(s.length, t.length); i++) {

        if (s === t) {
            return counter;
        }

        if (s !== t && s.length > t.length) {
            sArray.shift("");
            counter += 1;
        }

        if (s !== t && t.length > s.length) {
            tArray.shift("");
            counter += 1;
        }

        if (s !== t && t.length === s.length) {
            sArray.shift("");
            tArray.shift(""); 
            counter += 1;
        }
    }

    return counter;

}

console.log(shiftLeft("west", "test"));

Но это дает мне неправильное значение для рассматриваемого теста - счетчик для "test" и "west" должен равняться только 2, и это возвращает 4.

Моя логика неверна или это синтаксис цикла for или оба?

1 Ответ

3 голосов
/ 07 мая 2019

Проблема с вашим кодом заключается в том, что в конце каждой итерации вы обновляете sArray и tArray без обновления s и t.

Затем на следующей итерации вы проверяете, равны ли s и t, что никогда не будет так, если только они не были равны с начала.

Итак, вы также должны обновить s и t.


Также в этой части вашего кода:

if (s !== t && t.length === s.length) {
            sArray.shift("");
            tArray.shift(""); 
            counter += 1;
}

Не следует ли увеличить счетчик на 2? (Я вижу это как два шага, но это зависит от вас).


И, к сведению, использование s = s.substring(1); для удаления первого символа должно быть намного сложнее, чем работа с массивами ...

Ниже приведен фрагмент, использующий вашу собственную логику, но обращающийся к тому, что я упомянул выше. Надеюсь, это поможет!

function shiftLeft(s, t) {

    let counter = 0;

    while(Math.min(s.length, t.length) > 0) {

        if (s === t) {
            return counter;
        }

        if (s !== t && s.length > t.length) {
            s = s.substring(1);
            counter += 1;
        }

        if (s !== t && t.length > s.length) {
            t = t.substring(1);
            counter += 1;
        }

        if (s !== t && t.length === s.length) {
            s = s.substring(1);
            t = t.substring(1);
            counter += 2; //shouldn't this be 2 instead of 1?
        }
    }

    return counter;

}

console.log(shiftLeft("test", "yes"));

Редактировать: Оказывается, ваше условие цикла было неправильным. Счетчик i продолжает увеличиваться, в то время как Math.min(s.length, t.length) продолжает уменьшаться и приближаться к нулю, поэтому цикл остановится слишком рано. Реальная логика, которую мы хотим, это продолжать цикл до тех пор, пока одна из строк не станет пустой.

...