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

Подсчёт гласных в строке

2.2 Middle🔥 201 комментариев
#JavaScript Core

Условие

Напишите функцию countVowels(str), которая подсчитывает количество гласных букв в строке.

Требования

  1. Гласные буквы: a, e, i, o, u (английские)
  2. Регистр не важен (A и a считаются одной буквой)

Примеры

countVowels("hello");              // 2
countVowels("AEIOU");              // 5
countVowels("rhythm");             // 0
countVowels("The quick brown fox"); // 5
countVowels("");                   // 0

Бонус

Добавьте поддержку русских гласных: а, е, ё, и, о, у, ы, э, ю, я.

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

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

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

Решение

Задача на подсчёт гласных букв — простая на первый взгляд, но имеет несколько интересных вариантов реализации. Покажем разные подходы.

Решение 1: Регулярные выражения

Самый компактный и понятный способ:

function countVowels(str: string): number {
  // Регулярное выражение: ищем гласные (любой регистр)
  const vowels = str.match(/[aeiou]/gi);
  return vowels ? vowels.length : 0;
}

console.log(countVowels("hello"));              // 2
console.log(countVowels("AEIOU"));              // 5
console.log(countVowels("rhythm"));             // 0
console.log(countVowels("The quick brown fox")); // 5
console.log(countVowels(""));                   // 0

Анализ:

  • [aeiou] — класс символов, гласные английского алфавита
  • g флаг — глобальный поиск (все совпадения)
  • i флаг — игнорировать регистр
  • Временная сложность: O(n)
  • Очень компактно и читаемо

Решение 2: Цикл с массивом

Отсутствие зависимостей от regex:

function countVowelsLoop(str: string): number {
  const vowels = ["a", "e", "i", "o", "u"];
  let count = 0;
  
  for (const char of str.toLowerCase()) {
    if (vowels.includes(char)) {
      count++;
    }
  }
  
  return count;
}

Анализ:

  • Легко расширяется для других языков
  • Более явная логика
  • Временная сложность: O(n * m), где m = количество гласных (5)

Решение 3: Set для оптимизации

Лучше для производительности:

function countVowelsSet(str: string): number {
  const vowels = new Set(["a", "e", "i", "o", "u"]);
  let count = 0;
  
  for (const char of str.toLowerCase()) {
    if (vowels.has(char)) {
      count++;
    }
  }
  
  return count;
}

Анализ:

  • Временная сложность: O(n) — поиск в Set O(1)
  • Пространственная сложность: O(1) — 5 элементов
  • Для больших текстов быстрее, чем includes()

Решение 4: reduce (функциональный стиль)

Более декларативный подход:

function countVowelsFunctional(str: string): number {
  const vowels = new Set(["a", "e", "i", "o", "u"]);
  
  return Array.from(str.toLowerCase()).reduce(
    (count, char) => count + (vowels.has(char) ? 1 : 0),
    0
  );
}

// Или ещё более компактно
function countVowelsCompact(str: string): number {
  return str.toLowerCase()
    .split("")
    .filter(char => "aeiou".includes(char))
    .length;
}

Бонус: Поддержка русских гласных

Добавляем русские гласные:

function countVowelsMultilingual(str: string): number {
  // Комбинируем английские и русские гласные
  const vowels = new Set([
    // Английские
    "a", "e", "i", "o", "u",
    // Русские
    "а", "е", "ё", "и", "о", "у", "ы", "э", "ю", "я"
  ]);
  
  let count = 0;
  for (const char of str.toLowerCase()) {
    if (vowels.has(char)) {
      count++;
    }
  }
  
  return count;
}

// Или с регулярными выражениями
function countVowelsRegexMulti(str: string): number {
  // Регулярное выражение с английскими и русскими гласными
  const vowels = str.match(/[aeiouаеёиоуыэюя]/gi);
  return vowels ? vowels.length : 0;
}

console.log(countVowelsMultilingual("Hello мир"));        // 3 + 1 = 4
console.log(countVowelsMultilingual("Привет"));           // 2
console.log(countVowelsMultilingual("AEIOU АЕЁИОУЫЭЮЯ")); // 5 + 10 = 15

Решение 5: Объект для других языков

Максимальная гибкость:

interface VowelConfig {
  vowels: Set<string>;
}

function createCountVowels(config: VowelConfig) {
  return (str: string): number => {
    let count = 0;
    for (const char of str.toLowerCase()) {
      if (config.vowels.has(char)) {
        count++;
      }
    }
    return count;
  };
}

// Использование для разных языков
const countEnglishVowels = createCountVowels({
  vowels: new Set(["a", "e", "i", "o", "u"])
});

const countRussianVowels = createCountVowels({
  vowels: new Set(["а", "е", "ё", "и", "о", "у", "ы", "э", "ю", "я"])
});

const countBothVowels = createCountVowels({
  vowels: new Set([
    "a", "e", "i", "o", "u",
    "а", "е", "ё", "и", "о", "у", "ы", "э", "ю", "я"
  ])
});

console.log(countEnglishVowels("Hello world"));   // 3
console.log(countRussianVowels("Привет мир"));   // 3
console.log(countBothVowels("Hello привет"));    // 6

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

ПодходСкоростьГибкостьЧитаемостьДля собеседования
RegexХорошоСредняяОтличнаяЛучше
Цикл + массивНормальноВысокаяХорошоХорошо
SetОтличнаяВысокаяХорошоОтличная
ReduceНормальноСредняяСредняяМожет быть
FilterНормальноСредняяХорошоХорошо

Рекомендации для собеседования

  1. Начните с regex — компактно и понятно
  2. Обсудите временную сложность — O(n)
  3. Предложите вариант через цикл — более явный
  4. Упомяните Set — для оптимизации по памяти
  5. Реализуйте бонус — мультиязычность показывает гибкость

Мой выбор для production: Set + цикл — идеальный баланс скорости, читаемости и гибкости. Для быстрого прототипирования — регулярные выражения.