← Назад к вопросам

Как в Dart определить является ли строка палиндромом?

1.0 Junior🔥 171 комментариев
#Dart

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Как в Dart определить является ли строка палиндромом?

Палиндром — это строка, которая читается одинаково в обе стороны. Например, "казак", "А роза упала на лапу Азора". Это классическая задача на алгоритмы, которая проверяет понимание работы со строками и логики.

Простейший подход

Самый очевидный способ — перевернуть строку и сравнить с исходной:

bool isPalindrome(String text) {
  String cleaned = text.toLowerCase().replaceAll(RegExp(r'\s'), '');
  return cleaned == cleaned.split('').reversed.join('');
}

void main() {
  print(isPalindrome("казак"));              // true
  print(isPalindrome("hello"));              // false
  print(isPalindrome("а роза упала на лапу")); // true
}

Что происходит:

  • toLowerCase() — приводит все буквы к нижнему регистру
  • replaceAll(RegExp(r'\s'), '') — удаляет пробелы
  • split('') — разбивает строку на отдельные символы
  • reversed — переворачивает список
  • join('') — собирает обратно в строку
  • Сравниваем исходную со перевёрнутой

Оптимизированный подход: двойной указатель

Более эффективный алгоритм — сравнивать символы с начала и конца одновременно:

bool isPalindrome(String text) {
  String cleaned = text.toLowerCase().replaceAll(RegExp(r'[^a-z0-9а-я]'), '');
  
  int left = 0;
  int right = cleaned.length - 1;
  
  while (left < right) {
    if (cleaned[left] != cleaned[right]) {
      return false;
    }
    left++;
    right--;
  }
  
  return true;
}

void main() {
  print(isPalindrome("А роза упала на лапу Азора")); // true
  print(isPalindrome("Hello World"));                 // false
  print(isPalindrome("12321"));                       // true
  print(isPalindrome("race a car"));                  // false
}

Преимущества:

  • Временная сложность: O(n), но в среднем быстрее остаётся на половину
  • Не создаём новые строки и массивы
  • Можем вернуть false сразу же при нахождении несовпадения

Обработка специальных символов

Для реальных случаев нужно правильно обработать спецсимволы и пробелы:

bool isPalindrome(String text) {
  // Удаляем всё кроме букв и цифр
  String cleaned = text.toLowerCase()
    .replaceAll(RegExp(r'[^a-z0-9а-я]'), '');
  
  if (cleaned.isEmpty) return true;
  
  // Сравниваем с перевёртнутой версией
  return cleaned == cleaned.split('').reversed.join('');
}

void main() {
  // С пунктуацией
  print(isPalindrome("A man, a plan, a canal: Panama")); // true
  print(isPalindrome("Was it a car or a cat I saw?")); // true
  print(isPalindrome("Madam, I'm Adam"));              // true
  
  // Кириллица
  print(isPalindrome("Я иду с мечом судия"));         // true
  print(isPalindrome("А роза упала на лапу Азора")); // true
}

Рекурсивный подход

Для демонстрации рекурсии можно решить задачу рекурсивно:

bool isPalindromeRecursive(String text) {
  String cleaned = text.toLowerCase()
    .replaceAll(RegExp(r'[^a-z0-9а-я]'), '');
  
  bool checkPalindrome(int left, int right) {
    if (left >= right) return true;
    
    if (cleaned[left] != cleaned[right]) {
      return false;
    }
    
    return checkPalindrome(left + 1, right - 1);
  }
  
  return checkPalindrome(0, cleaned.length - 1);
}

void main() {
  print(isPalindromeRecursive("казак")); // true
}

Функциональный подход

Используя функциональный стиль Dart:

bool isPalindrome(String text) {
  final cleaned = text.toLowerCase()
    .replaceAll(RegExp(r'[^a-z0-9а-я]'), '');
  
  final reversed = cleaned.split('').reversed.join('');
  return cleaned == reversed;
}

// Или с расширением
extension PalindromeCheck on String {
  bool get isPalindrome {
    final cleaned = toLowerCase()
      .replaceAll(RegExp(r'[^a-z0-9а-я]'), '');
    return cleaned == cleaned.split('').reversed.join('');
  }
}

void main() {
  print("казак".isPalindrome);        // true
  print("hello".isPalindrome);        // false
}

Сравнение подходов

ПодходПамятьСкоростьЧитаемость
Переворот строкиO(n)O(n)Отличная
Двойной указательO(1)O(n)Хорошая
РекурсияO(n) stackO(n)Средняя
ФункциональныйO(n)O(n)Хорошая

На собеседовании

Оптимальный ответ:

  1. Начните с простого — перевернуть и сравнить
  2. Затем оптимизируйте — двойной указатель
  3. Обсудите граничные случаи — пустая строка, спецсимволы, кириллица
  4. Рассмотрите расширения — как сделать код более переиспользуемым

Палиндром — простая задача, но она хорошо показывает понимание алгоритмов и работы со строками в Dart.

Как в Dart определить является ли строка палиндромом? | PrepBro