Рекурсивная функция для соответствия строке против подстановочного шаблона

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

Следующая функция принимает 2 строки, 2-е (не 1-й) возможно содержащий *(звездочки).
* замена для строки (пустой, 1 символ или больше), это может появиться, появляются (только в s2) однажды, дважды, больше или нисколько, это не может быть смежно с другим * (ab**c), никакая потребность проверить это.

public static boolean samePattern(String s1, String s2)

Это возвращает true, если строки имеют тот же шаблон.
Это должно быть рекурсивно, не используют любые циклы, статические и глобальные переменные. Может использовать локальные переменные и перегрузку метода.

Может использовать только эти методы: charAt(i), substring(i), substring(i, j), length().

Примеры:

1: TheExamIsEasy; 2: The*xamIs*y → верный
1: TheExamIsEasy; 2: Th*mIsEasy* → верный
1: TheExamIsEasy; 2: * → верный
1: TheExamIsEasy; 2: TheExamIsEasy → верный
1: TheExamIsEasy; 2: The*IsHard → ЛОЖЬ

Я пытался сравнить символы один за другим с помощью charAt пока со звездочкой не встречаются, затем проверьте, является ли звездочка пустой сравнением, последовательный символ (i+1) с символом s1 в положении i, если верный - продолжают рекурсию с i+1 как противостоят для s2 & i как противостоят для s1;
если ложь - продолжает рекурсию с i+1 как противостоит для обоих.
Продолжите это, пока другая звездочка не будет найдена или конец строки.

Я не знаю, мой мозг теряет след вещей, не может сконцентрироваться, никакие указатели / подсказки? Я нахожусь в правильном направлении?

Кроме того, было сказано, что метод отслеживания в обратном порядке должен использоваться для решения этого.

Мой код до сих пор (не делает задания, даже теоретически):

public static boolean samePattern(String s1, String s2) {
    if (s1.equals(s2) || s2 == "*") {
        return true;
    }
    return samePattern(s1, s2, 1);
}
public static boolean samePattern(String s1, String s2, int i)
{
    if (s1.equals(s2))
        return true;
    if (i == s2.length() - 1) // No *'s found -- not same pattern.
        return false;

    if (s1.substring(0, i).equals(s2.substring(0, i)))
        samePattern(s1, s2, i+1);
    else if (s2.charAt(i-1) == '*')
        samePattern(s1.substring(0, i-1), s2.substring(0, i), 1); // new smaller strings.
    else
        samePattern(s1.substring(1), s2, i);
}
9
задан George Kagan 27 November 2016 в 20:55
поделиться

4 ответа

Вот Python "psudocode", который может помочь

def samePattern(s1,s2):
    if s2 == "*" or s1 == s2: return True
    if s1 == "": return False
    if s1[0] == s2[0]: return samePattern(s1[1:], s2[1:])
    if s2[0] == "*": return samePattern(s1, s2[1:]) or samePattern(s1[1:], s2)
    return False

Вот примерное руководство по преобразованию кода

s[0] = the first character
s[1:] = the string minus the first character
6
ответ дан 4 December 2019 в 13:45
поделиться

Вот пример решения, написанного на C #. Извините за отсутствие комментариев, но у меня не было на них времени: / Если они вам еще понадобятся завтра, я могу написать несколько, но я надеюсь, что вы ухватитесь за идею.

 public static bool CompareString(string s1, string s2, bool wildCard)
 {
        // Both strings are empty
        if ((s1.Length == 0) && (s2.Length == 0)) return true;

        // Second string is empty and there is wildCard character
        if (s2.Length == 0 && wildCard) return true;

        //First string is empty. Answer will be true only if all characters in second string are *.
        if (s1.Length == 0 && s2.Length > 0 && s2[0] == '*')
        {
            string newS2 = s2.Remove(0, 1);
            return CompareString(s1, newS2, true);
        }

        // One of the strings is empty, and second one is not.
        if (s1.Length * s2.Length == 0) return false;

        if (wildCard)
        {
            string newS1 = s1.Remove(0, 1);
            if (CompareString(newS1,s2,true) || CompareString(newS1,s2,false))
            {
                return true;
            }
        }
        else
        {
            if (s2[0] == '*')
            {
                string newS2 = s2.Remove(0,1);
                if (CompareString(s1,newS2,true) || CompareString(s1,newS2,false))
                {
                    return true;
                }
            }
            else
            {
                if (s1[0] == s2[0])
                {
                    string newS1 = s1.Remove(0,1);
                    string newS2 = s2.Remove(0,1);
                    return CompareString(newS1,newS2,false);
                }
                else
                {
                    return false;
                }
            }
        }
        return false;
    }
2
ответ дан 4 December 2019 в 13:45
поделиться

Когда вы имеете дело с подобными алгоритмами, часто бывает полезно разбить проблему на небольшие кусочки в уме.

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

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

Конечно, это рекурсия по строкам, поэтому вам придется иметь пару условий, управляющих неудачей / успехом, которые имеют дело с общее состояние строк - но это не суть проблемы - проверьте состояние строки в верхней части функции и двигайтесь дальше.

У меня есть алгоритм, который я придумал (11 строк кода плюс фигурные скобки), который я могу опубликовать, если вам нужно полное решение, но я не был уверен в вашем сообщении, хотите ли вы, чтобы вам дали алгоритм, или просто указатели.

2
ответ дан 4 December 2019 в 13:45
поделиться

Проблема с вашим текущим подходом заключается в том, что он не учитывает все возможные подстроки, которые * может соответствовать. Например, samePattern («ababababab», «a * b») должен возвращать true; * может соответствовать всем буквам строки, кроме первой и последней, но ваш код предполагает, что, поскольку следующая буква - b, * соответствует пустой строке.

Я предлагаю думать о samePattern как о «потреблении» двух своих входных строк при поиске совпадения. На каждом шаге samePattern должен смотреть только на первый символ каждой строки, чтобы решить, возможно ли совпадение с первым символом , и если да, то сделать рекурсивный вызов для проверки остальной части строки. Хитрость заключается в том, чтобы знать, что делать, когда вы дойдете до * в строке шаблона, поскольку он может использоваться или не использоваться для сопоставления первого символа в s1. Вам не нужно смотреть на оставшуюся часть строки, чтобы решить, что делать.

Поскольку это домашнее задание, я оставлю выяснение деталей того, что там происходит с вами, но, надеюсь, это заставит вас задуматься о правильном пути.

5
ответ дан 4 December 2019 в 13:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: