Maison  >  Article  >  développement back-end  >  La longueur de la plus petite sous-chaîne contenant toutes les voyelles

La longueur de la plus petite sous-chaîne contenant toutes les voyelles

王林
王林avant
2023-09-05 16:17:111023parcourir

La longueur de la plus petite sous-chaîne contenant toutes les voyelles

Un problème courant souvent rencontré dans les tâches de manipulation de chaînes est d'identifier la sous-chaîne la plus courte contenant chaque voyelle au moins une fois. Cette tâche a des applications dans divers domaines tels que l'analyse de données, la bioinformatique et le traitement du langage naturel. Le but est de trouver la plus petite partie consécutive d'une chaîne existante contenant ces cinq lettres (a, e, i, o, u) au moins une fois. Le processus de sélection pour résoudre ce défi comprend diverses techniques, telles que la mise en œuvre d'un algorithme de fenêtre glissante, l'utilisation d'un processus de hachage ou l'exploitation d'expressions régulières, entre autres. Trouver une solution robuste à ce problème devient souvent crucial, car de nombreux scénarios réels nécessitent des méthodes fiables de manipulation de texte.

Méthode

Il existe différentes façons de trouver la longueur de la plus petite sous-chaîne contenant toutes les voyelles.

Méthode 1. Méthode de la fenêtre coulissante

Méthode 2. Méthode du double pointeur

Méthode 3. Méthode du tableau de fréquences

Méthode 1 : Méthode de la fenêtre coulissante

Pour déterminer rapidement la taille de la sous-chaîne la plus courte contenant toutes les voyelles de chaque chaîne, utilisez la méthode de la fenêtre coulissante. Cette méthode utilise deux pointeurs, souvent appelés « gauche » et « droite », pour produire une fenêtre coulissante qui glisse le long de la chaîne.

Grammaire

Voici la syntaxe pour trouver la longueur minimale de sous-chaîne contenant toutes les voyelles en utilisant la méthode de la fenêtre coulissante -

def find_smallest_substring(string):
   vowels = {'a', 'e', 'i', 'o', 'u'}
   unique_vowels = set()
   start = 0
   end = 0
   min_length = float('inf')
    
   while end < len(string):
      # Expand the window
      if string[end] in vowels:
         unique_vowels.add(string[end])
        
      # Contract the window
      while len(unique_vowels) == len(vowels):
         min_length = min(min_length, end - start + 1)
         if string[start] in vowels:
         unique_vowels.remove(string[start])
         start += 1
        
       end += 1
    
   return min_length

Algorithme

Étape 1 - Utilisez une fenêtre coulissante de taille n (la longueur de la chaîne) et déplacez-la de gauche à droite.

Étape 2 - À chaque position dans la fenêtre, assurez-vous que la sous-chaîne est entièrement composée de voyelles. Si tel est le cas, mettez à jour la longueur minimale de la sous-chaîne trouvée jusqu'à présent.

Étape 3 - Utilisez une table de hachage pour enregistrer le nombre de répétitions de chaque voyelle dans une sous-chaîne afin de déterminer si la sous-chaîne contient toutes les voyelles.

Étape 4 - Si la sous-chaîne ne contient pas toutes les voyelles, continuez le test en déplaçant la fenêtre vers la droite et en répétant le processus jusqu'à ce que toutes les sous-chaînes potentielles aient été testées.

La traduction chinoise de

Exemple 1

est :

Exemple 1

Pour déterminer si un caractère donné est une voyelle dans cette implémentation, nous définissons la fonction d'assistance isVowel. Pour décrire la fenêtre coulissante, nous utilisons également deux pointeurs à gauche et à droite.

Si le caractère actuel est une voyelle, nous étendons d'abord la fenêtre en l'ajoutant à la collection de fenêtres à l'intérieur de la boucle while. Vérifiez ensuite que la taille de la collection de fenêtres est de 5 (c'est-à-dire que toutes les voyelles sont présentes). Si tel est le cas, modifiez la réponse et réduisez la taille de la fenêtre en éliminant le caractère le plus à gauche de l'ensemble de fenêtres jusqu'à ce qu'il soit inférieur à 5.

Le résultat de la boucle renvoie la longueur de la plus petite sous-chaîne contenant toutes les voyelles.

#include <iostream>
#include <unordered_set>
using namespace std;

bool isVowel(char c) {
   return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u';
}
int smallestSubstring(string s) {
   unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};
   unordered_set<char> window;
   int n = s.length(), left = 0, right = 0, ans = n + 1;
    
   while (right < n) {
      // Expand the window by adding the current character
      char c = s[right];
      if (isVowel(c)) {
         window.insert(c);
      } 
      right++;
        
      // close the window by removing the leftmost character
      while (window.size() == 5) {
         ans = min(ans, right - left);
         char d = s[left];
         if (isVowel(d)) {
            window.erase(d);
         }
         left++;
      }
   }
   return ans <= n ? ans : 0;
}

int main() {
   string s = "aeeioubcdfuioaei";
   int len = smallestSubstring(s);
   cout << "Length of smallest substring containing all vowels: " << len << endl;
   return 0;
}

Sortie

Length of smallest substring containing all vowels: 6

Méthode 2 : Méthode du double pointeur

La méthode du double pointeur est une méthode populaire pour résoudre rapidement divers problèmes de manipulation de chaînes. La technique du double pointeur est très utile pour déterminer la longueur de la plus petite sous-chaîne contenant toutes les voyelles.

Grammaire

C'est la syntaxe pour trouver la longueur minimale de sous-chaîne contenant toutes les voyelles en utilisant la méthode du double pointeur−

function findSmallestSubstring(str):
   vowels = {'a', 'e', 'i', 'o', 'u'}
   count = 0
   left = 0
   minLength = infinity

   for right in range(length of str):
      if str[right] is a vowel:
         count += 1

       while count is same as the total number of vowels:
         minLength = minimum (minLength, right - left + 1)

         if str[left] is a vowel:
         count -= 1

         left += 1

   return minLength

Algorithme

Étape 1 - Réglez les pointeurs de début et de fin pour qu'ils pointent respectivement vers la position de départ de la chaîne.

Étape 2 - Continuez à déplacer le pointeur de fin vers la droite jusqu'à ce que vous trouviez une sous-chaîne contenant uniquement des voyelles.

Étape 3 - Si nous trouvons une sous-chaîne qui contient toutes les voyelles, déplacez le curseur de départ vers la droite jusqu'à ce qu'elle ne contienne plus toutes les voyelles.

Étape 4 - Continuez à déplacer le pointeur de queue vers la droite jusqu'à ce que vous trouviez une nouvelle sous-chaîne contenant toutes les voyelles, puis déplacez le pointeur de début vers la droite jusqu'à ce que la sous-chaîne ne contienne plus toutes les voyelles.

Étape 5 - Actualisez la longueur de sous-chaîne la plus courte jusqu'à présent.

La traduction chinoise de

Exemple 2

est :

Exemple 2

Dans cet exemple, pour représenter la fenêtre glissante, on retient deux pointeurs, gauche et droite. De gauche à droite, nous parcourons la chaîne str, vérifiant à chaque fois si le caractère actuel est une voyelle. Pour garder une trace des voyelles observées jusqu'à présent, si c'est une voyelle, nous l'ajoutons à l'ensemble consulté.

Nous déplaçons le curseur gauche pour réduire la longueur de la sous-chaîne, une fois que nous voyons que la sous-chaîne contient toutes les voyelles. Ce processus se poursuit jusqu'à ce que le curseur droit atteigne la fin de la chaîne.

Renvoie la longueur de la sous-chaîne la plus courte contenant toutes les voyelles. Si aucune sous-chaîne de ce type n’existe, 0 est renvoyé.

#include <iostream>
#include <string>
#include <unordered_set>
using namespace std;

int smallestSubstringLength(const string& str) {
   int n = str.length();
   unordered_set<char> vowels = {'a', 'e', 'i', 'o', 'u'};

   unordered_set<char> seen;
   int left = 0, right = 0;
   int smallestLength = n + 1;

   while (right < n) {
      if (vowels.find(str[right]) != vowels.end()) {
         seen.insert(str[right]);
      }

      if (seen.size() == vowels.size()) {
         while (seen.size() == vowels.size()) {
            if (right - left + 1 < smallestLength) {
               smallestLength = right - left + 1;
            }

            if (vowels.find(str[left]) != vowels.end()) {
               seen.erase(str[left]);
            }

            left++;
         }
      }
      right++;
   }
   return (smallestLength == n + 1) ? 0 : smallestLength;
}

int main() {
   string str = "aeeiiouuobcdaeiou";
   int length = smallestSubstringLength(str);
   cout << "Length of the smallest substring containing all vowels: " << length << endl;
   return 0;
}

Sortie

Length of the smallest substring containing all vowels: 7

Méthode 3. Méthode du tableau de fréquences

Utilisez la méthode du tableau de fréquences pour mesurer la sous-chaîne la plus courte contenant toutes les voyelles de chaque chaîne. Cela nécessite de créer un tableau de fréquences pour enregistrer le nombre d'occurrences de voyelles, puis de parcourir le texte à plusieurs reprises pour localiser la sous-chaîne souhaitée.

Grammaire

La syntaxe pour trouver la plus petite sous-chaîne contenant toutes les voyelles est la suivante -

# Check if all vowels are present in the current substring
if all(freq[vowel] > 0 for vowel in vowels):
   # Update the minimum length if needed
   min_length = min(min_length, right - left + 1)
    
   # Move the left pointer to find a potentially smaller substring
   while left < right:
      freq[input_string[left]] -= 1
      if freq[input_string[left]] == 0:
      break
      left += 1

# Move the right pointer to expand the current substring
right += 1

算法

步骤 1 − 为了记录每个元音字母(a,e,i,o,u)的重复次数,从大小为5的频率数组开始。

第二步 - 创建开始和结束指针,分别标记字符串的开头。

第三步 - 继续将结束指针向右移动,直到每个元音字母至少被听到一次。

步骤4 − 将起始指针向右移动,直到子字符串不再包含至少每个元音字母的重复。

第五步 - 调整已经识别出的子字符串的最小长度,然后将结束指针向右移动,直到发现一个包含所有元音字母的新子字符串。

步骤 6 - 在每个位置更新频率数组,以验证当前子字符串是否包含所有元音字母。

Example 3

的中文翻译为:

示例3

在这个例子中,函数min Length Substring接受一个字符串作为输入,并计算包含所有五个元音字母(a,e,i,o,u)的最小子字符串的长度。

该函数使用名为vowelCount的频率数组来计算子字符串中的每个元音字母的数量。它通过维护一个名为distinctVowels的计数器来跟踪子字符串中不同元音字母的数量。

通过使用两个指针,即start和finish,该函数循环遍历字符串,对每个遇到的元音字母增加频率数组的vowelCount。一旦找到了每个不同的元音字母,子字符串就开始从起始位置收缩,直到没有不同的元音字母为止。如果发现了更短的子字符串,则更新最小子字符串的长度。

主要功能使用字符串来展示如何使用最小长度子字符串方法,通过输入包含所有元音字母的最短子字符串的长度。

#include <iostream>
#include <climits>
using namespace std;

int minLengthSubstring(const string& str) {
   const string vowels = "aeiou";
   int vowelCount[5] = {0};  // Frequency array for vowels
   int distinctVowels = 0;  // Count of distinct vowels in the substring

   // Initialize the minimum length to maximum integer value
   int minLength = INT_MAX;

   int start = 0, end = 0;
   while (end < str.length()) {
      // Increment frequency for vowel at 'end' position
      for (int i = 0; i < 5; i++) {
         if (str[end] == vowels[i]) {
            if (vowelCount[i] == 0) {
               distinctVowels++;
            }
            vowelCount[i]++;
            break;
         }
      }

      // If all distinct vowels are found
      if (distinctVowels == 5) {

         while (start < end) {
            // Update minimum length if a shorter substring is found
            if (minLength > end - start + 1) {
               minLength = end - start + 1;
            }

            // Decrement frequency for vowel at 'start' position
               for (int i = 0; i < 5; i++) {
               if (str[start] == vowels[i]) {
                  vowelCount[i]--;
                  if (vowelCount[i] == 0) {
                     distinctVowels--;
                  }
                  break;
               }
            }
            start++;

            // Break if any distinct vowel is missing in the substring
            if (distinctVowels < 5) {
               break;
            }
         }
      }

      end++;
   }

   return minLength == INT_MAX ? -1 : minLength;
}

int main() {
   string str = "aeeioubcdofu";
   int length = minLengthSubstring(str);

   if (length == -1) {
      cout << "No substring containing all vowels found." << endl;
   } else {
      cout << "Length of the smallest substring containing all vowels: " << length << endl;
   }
   return 0;
}

输出

Length of the smallest substring containing all vowels: 6

结论

总之,找到La longueur de la plus petite sous-chaîne contenant toutes les voyelles是一个可以使用各种技术高效解决的问题。通过使用滑动窗口方法或散列元音字母的出现次数,可以遍历字符串并识别满足要求的最小子字符串。这些方法的时间复杂度通常是线性的,适用于大规模输入。然而,重要的是处理边界情况并考虑可能影响解决方案的额外约束条件。总的来说,通过正确的算法方法,可以有效地确定La longueur de la plus petite sous-chaîne contenant toutes les voyelles。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer