Проверка наличия палиндрома в слове в строке

Я хочу узнать, содержит ли строка слово-палиндром. Например, hellosannasmith содержит слово-палиндром и должно вернуть sannas, однако givemefood должно вернуть none. Сначала я попробовал это с помощью 2 циклов for, затем начал думать, почему бы не использовать цикл while, но прежде чем я начну идти по маршруту цикла while, я хочу посмотреть, можно ли это сделать сначала с помощью 2 циклов for.

Мне удалось поместить san в новую строковую переменную палиндрома, но я не уверен, что еще я здесь упускаю или упускаю из виду. Любая помощь будет принята с благодарностью.

function SearchingChallenge(str) {
  var palindromeStr = "";

  for (var i = 0; i < str.length / 2; i++) {
    for (var j = str.length - 1; str.length / 2 < j; j--) {
      if (str[i + 1] == str[j - 1] && str[i] == str[j]) {
        palindromeStr += str[i];
      }
    }
  }

  if (palindromeStr == "") {
    return "none";
  }

  return palindromeStr;
}

console.info(SearchingChallenge('hellosannasmith'));
console.info(SearchingChallenge('givemefood'));

Какие шаги вы предприняли для устранения этой проблемы?

mykaf 03.07.2024 22:00

@mykaf Я использую ручку и бумагу, чтобы визуализировать результат, и пришел к выводу, что условие if можно исправить на что-то «лучшее», но пока не знаю, как к этому подойти

DonDavid12 03.07.2024 22:03

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

Unmitigated 04.07.2024 00:09

@DonDavid12 DonDavid12 Какое здесь определение слова? Любая строка длиной не менее 2?

Unmitigated 04.07.2024 00:10

Это не было указано в задаче задачи, но да, давайте пока остановимся на этом @Unmitigated

DonDavid12 04.07.2024 00:12

Вам нужно найти самую длинную палиндромную подстроку или любую?

Unmitigated 04.07.2024 00:19

Предполагая, что в подстроке @Unmitigated имеется один палиндром

DonDavid12 04.07.2024 00:21

@ DonDavid12 Однако в 'hellosannasmith' есть еще один палиндром: 'll'.

Unmitigated 04.07.2024 01:17

@Unmitigated При рассмотрении двухбуквенных слов. А еще: nn и anna кстати.

KooiInc 05.07.2024 14:08

@KooiInc Да, это правда. В итоге я просто реализовал метод поиска самой длинной палиндромной подстроки.

Unmitigated 06.07.2024 21:10
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
10
123
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

  • Вы можете определить Set(), включая все слова, а затем использовать динамическое программирование, чтобы найти самый длинный палиндром.

  • Вы также можете добавить некоторые условия для возврата палиндрома, найденного в наборе. (Из вопроса неясно).

const words = new Set(["hello", "sannas", "smith", "give", "me", "food"]);

function SearchingChallenge(str) {
  const n = str.length;
  if (n === 0) return "none";

  let res = "";
  const dp = Array.from({ length: n }, () => Array(n).fill(false));

  for (let len = 1; len <= n; len++) {
    for (let i = 0; i <= n - len; i++) {
      const j = i + len - 1;
      if (len === 1) {
        dp[i][j] = true;
      } else if (len === 2) {
        dp[i][j] = str[i] === str[j];
      } else {
        dp[i][j] = str[i] === str[j] && dp[i + 1][j - 1];
      }
      if (dp[i][j] && len > res.length) {
        res = str.slice(i, j + 1);
      }
    }
  }

  return words.has(res) ? res : "none";
}

console.info(SearchingChallenge("hellosannasmith"));
console.info(SearchingChallenge("givemefood"));

Примечание:

  • Эту функцию необходимо изменить, чтобы она соответствовала требованиям задачи.

Следует учитывать, что ваш внешний цикл просматривает только первую половину строки, а внутренний цикл просматривает только вторую половину строки, то есть вы не проверяете все возможные подстроки. Ваш подход учитывает только то, существует ли он в центре строки.

Еще одно замечание: ваше условие if (str[i + 1] == str[j - 1] && str[i] == str[j]) проверяет только пары символов в указанной позиции. Таким образом, вы выполняете частичную проверку символов, а не всю подстроку. Таким образом, вы в конечном итоге строите свою строку, когда совпадают две пары, что не гарантирует, что это палиндром.

Попробуйте сделать его более читабельным и надежным, изменив циклы:

  for (let i = 0; i < str.length; i++) {
    for (let j = i + 1; j <= str.length; j++) {

Затем вы можете построить свою подстроку, используя эти индексы

Ответ принят как подходящий

Во-первых, сравнивая str[i] = str[j] вы можете прийти к «палиндрому», не имея палиндрома. визуализация «abcdefcba»: для i=1,2,3, j=n-1,n-2,n-3 str[i] === str[j]. однако они не связаны, потому что между ними есть другие вещи.

Во-вторых, в той же проверке, которую вы проверяете как str[i]===str[j], так и str[i+1]===str[j-1], это означает, что последний символ, отвечающий критериям, не будет вводить результат (кроме случая, когда они встречаются в центре, как в вашем первом примере)

Итак, вам нужно для каждого заданного интервала проверять, является ли подстрока в данном интервале палиндромом.

Проверьте приведенный ниже пример:

function isPalindrome(str) {
  return str === str.split('').reverse().join('');
}

function SearchingChallenge(str) {

  if (str.length <= 1) return 'none';
  
  for(let i=0;i<str.length-3;i++) {
    for(let j=str.length-1; j>i+2; j--) {
        
        const substr = str.substring(i, j);
        if (isPalindrome(substr)) return substr;
    }
  }

  return 'none';
}

console.info(SearchingChallenge('hellosannasmith'));
console.info(SearchingChallenge('givemefood'));
console.info(SearchingChallenge('abcdef'));
console.info(SearchingChallenge('someawesomeemosik'));

И наконец, помните две вещи:

  1. В строке может быть более одного палиндрома. поэтому вам нужно решить, вернете ли вы первый экземпляр или вернете массив всех найденных палиндромов. (в приведенном выше примере я возвращаюсь первым найденным)
  2. Вы должны определить минимальное количество символов принятого палиндрома. Вероятно, 1 символ вы не хотите считать палиндромом. как насчет 2? "аа" - это палиндром? и 3? тогда во втором примере givemefood, eme - это палиндром. в приведенном выше примере минимальная длина палиндрома установлена ​​на треть. но это нужно определить

Это помогает, но я пытаюсь понять, почему во втором цикле мы решили использовать j>i+2 и почему в данном случае выбрали +2?

DonDavid12 04.07.2024 00:11

Можете ли вы исправить повторяющиеся ошибки в написании слова «палиндром»?

Barmar 04.07.2024 00:14

@ DonDavid12 DonDavid12 это связано со вторым пунктом, который я указал в конце. Вопрос в том, какова минимальная длина палиндрома, который вы считаете палиндромом. в моем примере я установил 3 буквы. Для этого мне нужно, чтобы каждая подстрока, которую я проверяю, содержала как минимум 3 буквы, то есть j-i >=3 или j-i>2.

Yosef Tukachinsky 05.07.2024 01:05

Вы можете просто использовать алгоритм Манахера, чтобы найти самую длинную палиндромную подстроку за линейное время (O(N)) по количеству символов в строке.

function findLongestPalindromeSubstring(str) {
  const pOdd = Array(str.length).fill(0), pEven = Array(str.length).fill(0);
  let lOdd = 0, rOdd = 0, lEven = 0, rEven = 0, maxLen = 0, start = 0;
  for (let i = 0; i < str.length; i++) {
    if (rOdd > i) pOdd[i] = Math.min(rOdd - i, pOdd[lOdd + rOdd - i]);
    while (i - pOdd[i] >= 0 && i + pOdd[i] < str.length &&
      str[i - pOdd[i]] === str[i + pOdd[i]]) ++pOdd[i];
    if (i + pOdd[i] > rOdd) lOdd = i - pOdd[i], rOdd = i + pOdd[i];
    if (2 * pOdd[i] - 1 > maxLen) {
      maxLen = 2 * pOdd[i] - 1;
      start = i - pOdd[i] + 1;
    }
    if (rEven > i) pEven[i] = Math.min(rEven - i, pEven[lEven + rEven - i + 1]);
    while (i - 1 - pEven[i] >= 0 && i + pEven[i] < str.length
      && str[i - 1 - pEven[i]] === str[i + pEven[i]]) ++pEven[i];
    if (i + pEven[i] > rEven) lEven = i - 1 - pEven[i], rEven = i + pEven[i];
    if (2 * pEven[i] > maxLen) {
      maxLen = 2 * pEven[i];
      start = i - pEven[i];
    }
  }
  return maxLen > 1 ? str.slice(start, start + maxLen) : 'none';
}
console.info(findLongestPalindromeSubstring('hellosannasmith'));
console.info(findLongestPalindromeSubstring('givemefood'));
console.info(findLongestPalindromeSubstring('abc'));

> просто используйте 9 локальных привязок, несколько вложенных циклов, 14 условных операторов, 13 мутаций и еще один цикл для наглядности!

Mulan 05.07.2024 14:14

чтобы улучшить этот ответ, я думаю, вам следует связать алгоритм и включить базовое объяснение того, как он работает. Я поклонник оператора запятой, но мне интересно, почему он применяется непоследовательно? То есть, почему некоторые консеквенты if получают ,, тогда как другие получают { ...; ...; }?

Mulan 05.07.2024 14:17

@Мулан, я ценю обратную связь. Оглядываясь назад, возможно, слово «простой» было неправильным; В основном я имел в виду, что это стандартный метод эффективного решения большинства задач палиндрома. Что касается неиспользования везде оператора запятой, я старался избежать чрезмерной горизонтальной прокрутки в фрагменте кода. Кроме того, я написал этот код по памяти, не следуя конкретной статье. Я мог бы дать ссылку на страницу Википедии, но там используется слегка измененная версия алгоритма.

Unmitigated 06.07.2024 21:08

Я думаю, что проблема, которую вы описываете, заключается в следующем Самая длинная палиндромная подстрока

  1. Вы создаете цикл for для перебора символов строки.
  2. внутри цикла точки 1 вы напишете цикл для расширения влево и вправо. это поможет вам найти палиндром, длина которого может быть нечетной.
  3. внутри цикла точки 1 вы напишете еще один цикл для расширения слева и справа + 1, чтобы приспособить палиндром четной длины.

У меня нет javascript, но вот для Java

public String longestPalindrome(String s) {
        int n = s.length();

        int maxLen = 0;
        int maxL = 0;
        int maxR = 0;
        for (int i = 0; i < n ; i++) {
            int l = i, r = i;

            while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
                int len = r-l+1;
                if (len > maxLen) {
                    maxLen = len;
                    maxL = l;
                    maxR = r;
                }
                l--;
                r++;
            }

            l = i; r = i + 1;

            while (l >= 0 && r < n && s.charAt(l) == s.charAt(r)) {
                int len = r-l+1;
                if (len > maxLen) {
                    maxLen = len;
                    maxL = l;
                    maxR = r;
                }
                l--;
                r++;
            }
        }

        return s.substring(maxL, maxR+1);

    }

Строка может содержать несколько палиндромов. Вот функция, которая может вернуть их все (массив) или просто подтвердить наличие палиндрома в заданной строке (истина/ложь). Перед проверкой входная строка преобразуется в строку, содержащую только [a-zA-Z] (таким образом, все пробелы, вставки и т. д. удаляются).

Поиграйте с этим кодом (более проработанной версией) @Stackblitz

const strings = JSON.parse(document.querySelector(`#strings`)
  .content.textContent);
const result = document.querySelector(`#result`);

// just check for palindrome existence
strings.forEach(string => {
  const found = getPalindromesInString({str2Check: string, single: true});
  result.innerHTML += `<b>Are there palindromes in</b>\n<i>${
    JSON.stringify(string)}</i>?<span>${
      found.error 
      ? ` => ${found.error}` : found ? ` => SURE` : ` => NOPE`}
    </span>\n`;
});

result.innerHTML += `<hr>`;

// retrieve all palindromes
strings.forEach(string => {
  const found = getPalindromesInString({str2Check: string});
  result.innerHTML += [
    `<b>All palindromes in</b>\n<i>${JSON.stringify(string)}</i>`,
    `${JSON.stringify(found, null, 2)}`]
    .join(`\n`) + `\n\n`;
});

function getPalindromesInString({ 
    str2Check, 
    caseSensitive = false, 
    single = false, 
    isPalindrome = stringIsPalindromeFactory() } = {}) {

  if ( str2Check?.constructor !== String || str2Check?.length <= 1 ) {
    return {error: `invalid input`};
  }
  
  str2Check = str2Check.replace(/[^a-z]/gi, ``);
  const result = [];
  
  
  for (let i = 0; i < str2Check.length; i += 1) {
    for (let j = str2Check.length; j > i + 2; j -= 1) {
        const substr = str2Check.substring(i, j);
        const palindromeFound = substr.length > 1
          && isPalindrome(substr, caseSensitive);
        palindromeFound && result.push(substr);
    }
  }
  
  return single ? result.length > 0 : result;
}

// Recursive palindrome determination
function stringIsPalindromeFactory() {
  return function maybePalindrome(string, cs = false) {
    const lc = cs ? string : string?.toLowerCase();
    return lc[0] !== lc.at(-1) ? false : tail(lc.slice(1, -1));
  };

  function tail(str) {
    return !str.length 
      ? true : str[0] !== str.slice(-1) 
        ? false : tail(str.slice(1, -1));
  };
}
b {color: green; }

i {
  display: inline-block; 
  margin-left: 1rem;
  color: blue; 
}

span {color: red; }
<template id = "strings">[
  "I don't think we'll find palindromes",
  "It's Anna I am talking about, or quod non so m eawe so meem sos and finally tattarrattat",
  "A man, a plan, a canal: Panama",
  "T. Eliot, top bard, notes putrid tang emanating, is sad; I'd assign it a name: gnat dirt upset on drab pot toilet.",
  {"invalid": "input"} ]
</template>

<pre id = "result"></pre>

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