Maison  >  Article  >  développement back-end  >  Disposez les chaînes de manière à ce que le nombre de caractères qu'elles contiennent soit supérieur au nombre de caractères adjacents.

Disposez les chaînes de manière à ce que le nombre de caractères qu'elles contiennent soit supérieur au nombre de caractères adjacents.

PHPz
PHPzavant
2023-09-24 11:09:10667parcourir

Disposez les chaînes de manière à ce que le nombre de caractères quelles contiennent soit supérieur au nombre de caractères adjacents.

La manipulation des chaînes est cruciale dans une variété de scénarios de résolution de problèmes. La permutation d'une chaîne donnée optimise le nombre de caractères supérieur au nombre de caractères adjacents. Il s'agit d'un casse-tête intéressant qui nécessite de réorganiser les caractères d'une chaîne pour générer autant de paires de caractères adjacents que possible, où se trouvent les caractères. ceux de gauche sont plus petits que les caractères de droite. p>

Méthode

Il existe plusieurs façons de résoudre les permutations de chaînes où le nombre maximum de caractères est supérieur au nombre de caractères directement adjacents.

Méthode 1 − Retour en arrière et élagage −

Méthode 2 - Programmation dynamique -

Méthode 3 - Algorithme de tas-

Méthode 4 - Ordre du dictionnaire avec élagage -

Méthode 1 : Retour en arrière et élagage

  • Générez toutes les permutations de la chaîne à l'aide d'un algorithme de backtracking.

  • A chaque étape, vérifiez si l'arrangement actuel a plus de caractères que ses voisins supérieurs au maximum trouvé jusqu'à présent.

  • Sinon, taillez la branche tôt et revenez en arrière pour éviter des calculs inutiles.

Grammaire

function backtrack_permutation(string):
   n = length(string)
   max_count = [0]  
  • Stockez le nombre maximum de caractères supérieur aux caractères adjacents

result = [None] * n 
  • Enregistrer l'arrangement final

function backtrack(curr_permutation, used_chars):
nonlocal max_count
if length(cu permutation) == n:
  • Comptez le nombre de caractères plus grands que les caractères adjacents

count = 0
   for i in range(1, n - 1):
      if cu permutation [i - 1] < cu permutation[i] > cu permutation [i + 1]:
   count += 1
      if count > max count [0]:
      max count [0] = count
      result [:] = cu permutation  
  • Mettre à jour les résultats

return
   for i in range(n):
      if not used_chars[i]:
  • Choisissez le personnage suivant

used_chars[i] = true
curr_permutation.append(string[i])
  • Retour à la position suivante

backtrack(curr_permutation, used_chars)
  • Annuler la sélection

used_chars[i] = false
curr_permutation.pop()
  • Démarrez le processus de retour en arrière

used_chars = [false] * n 
  • Suivez les caractères utilisés

curr_permutation = []
backtrack(curr_permutation, used_chars)

return result.

Algorithme

Étape 1 - Démarrez max_permutation avec une chaîne vide.

  • La fonction auxiliaire de traçabilité (current_permutation, left_characters) doit être définie.

Étape 2 - Si la chaîne restant_characters est vide -

  • Si la longueur de la permutation actuelle est plus longue que la longueur de la plus grande permutation, définissez max_permutation sur current_permutation.

  • Retour.

Étape 3 - Dans une itération, parcourez chacun des caractères restants c -

  • Ajoutez c à current_permutation pour créer new_permutation.

  • Si la longueur de new_permutation est supérieure à 1 et que son dernier caractère n'est pas plus long que ses caractères précédents, ignorez cette itération.

  • Prenez c à partir des personnages_restants et générez un nouveau new_remaining.

  • Retraçage des appels itératifs (new_permutation, new_remaining).

Étape 4 - Appelez la fonction de traçage, en utilisant le texte d'entrée comme personnages_restants et la chaîne vide comme permutation_actuelle.

Étape 5 - Fournissez la sortie max_permutation.

Exemple 1

Ce programme fonctionne en triant d'abord la chaîne d'entrée "abcd" par ordre croissant. Chaque permutation possible est ensuite générée à l'aide d'une fonction de retour en arrière qui ne considère que les caractères supérieurs au caractère précédent, évitant ainsi les permutations répétées ne répondant pas aux critères. De plus, la fonction isValidPermutation évalue chaque caractère par rapport à son caractère précédent, renvoyant false pour tout caractère égal ou inférieur à ce dernier.

Le résultat est que ce processus ciblé crée toutes les permutations valides dans lesquelles le nombre maximum de chaque caractère est supérieur à celui de ses caractères voisins. Nous sommes libres de personnaliser davantage les chaînes d'entrée, le code et la logique donnés pour répondre aux besoins individuels.

#include <iostream>
#include <string>
#include <algorithm>

using namespace std;
int maxCount = 0;

bool isValidPermutation(const string& str) {
   for (int i = 1; i < str.length(); i++) {
      if (str[i] <= str[i - 1]) {
         return false;
      }
   }
   return true;
}

void backtrack(string& str, int pos) {
   if (pos == str.length()) {
      if (isValidPermutation(str)) {
         cout << str << endl;
      }
      return;
   }

   for (int i = pos; i < str.length(); i++) {
      swap(str[pos], str[i]);
      if (str[pos] > str[pos - 1]) {
         backtrack(str, pos + 1);
      }
      swap(str[pos], str[i]);
   }
}

int main() {
   string input = "abcd";
   sort(input.begin(), input.end());  // Sort the input string initially
   backtrack(input, 1);

   return 0;
}

Sortie

abcd

Méthode 2 : Programmation dynamique

  • Utilisez la programmation dynamique pour générer progressivement des permutations de chaînes.

  • Commencez avec un préfixe vide, considérez toutes les positions possibles et ajoutez-y des caractères de manière itérative.

  • Maintenez le nombre de caractères du préfixe actuel supérieur à ses caractères adjacents.

  • Élaguez les branches dont le nombre est tombé en dessous de la valeur maximale trouvée jusqu'à présent.

Grammaire

def find_max_permutation(string):
   n = len(string)
   dp = [0] * n
   dp[0] = 1
  • Boucle de programmation dynamique

for i in range (1, n):
  • Vérifiez si le caractère actuel est plus grand que son caractère adjacent

if string[i] > string[i-1]:
  • Si oui, augmentez le nombre de 1

dp[i] = dp[i-1] + 1
else:
  • Sinon, le décompte est le même

dp[i] = dp[i-1]
  • Trouver le nombre maximum dans le tableau dp

max_count = max(dp)

return max_count

Algorithme

Étape 1 - Créez une fonction appelée maxPerm(str) qui accepte une chaîne en entrée et renvoie la permutation de la chaîne la plus longue qui satisfait à la condition spécifiée.

Étape 2 - Initialisez d'abord un tableau (appelé dp) de longueur n, où n est égal à la longueur de la chaîne d'entrée str. La chaîne de permutation maximale se terminant à la position i est stockée dans chaque élément dp[i].

Étape 3 - Initialisez dp[0] au premier caractère de la chaîne str.

Étape 4 - Parcourez les caractères de str de l'index 1 à n-1 -

  • 初始化一个空字符串curr来存储当前最大排列字符串。

  • 对于索引 i 处的每个字符,将其与索引 i-1 处的前一个字符进行比较。

  • 如果 str[i] 大于 str[i-1],将 str[i] 添加到 curr 中。

  • 否则,将 str[i-1] 追加到 curr 中。

  • 使用 dp[i-1]curr 之间的最大值更新 dp[i]

第5步 - 循环完成后,最大排列字符串将存储在dp[n-1]中。

第 6 步 - 返回 dp[n-1] 作为结果。

Example 2

的中文翻译为:

示例2

在此示例中,输入字符串被硬编码为“abcbdb”。 findMaxPermutation 函数使用动态编程来计算每个索引处大于其相邻字符的最大字符数。然后,它通过回溯表来重建具有最大计数的字符串。生成的最大排列在 main 函数中打印。

#include <iostream>
#include <string>
#include <vector>

std::string findMaxPermutation(const std::string& str) {
   int n = str.length();
    
   // make a table to store the maximum count of characters
   // larger than their adjacent characters
   std::vector<std::vector<int>> dp(n, std::vector<int>(2, 0));

   // Initialize the table for the base case
   dp[0][0] = 0; // Count when str[0] is not included
   dp[0][1] = 1; // Count when str[0] is included
    
   // Calculate the maximum count for each index
   for (int i = 1; i < n; i++) {
      // When str[i] is not involved, the count is the maximum
      // when str[i-1] is included or not 
      dp[i][0] = std::max(dp[i-1][0], dp[i-1][1]);
        
      // When str[i] is involved, the count is the count when
      // str[i-1] is not included plus 1
      dp[i][1] = dp[i-1][0] + 1;
   }
    
   // The more count will be the largest of the last two values
   int maxCount = std::max(dp[n-1][0], dp[n-1][1]);

   // Reconstruct the string with the maximum count
   std::string maxPerm;
   int i = n - 1;
   int count = maxCount;
    
   // Start from the end and check which character to include
   while (i >= 0) {
      if ((dp[i][0] == count - 1 && dp[i][1] == count) || (dp[i][0] == count && dp[i][1] == count)) {
         maxPerm = str[i] + maxPerm;
         count--;
      }
      i--;
   }
   return maxPerm;
}
int main() {
   std::string str = "abcbdb";
   std::string maxPerm = findMaxPermutation(str);
    
   std::cout << "String: " << str << std::endl;
   std::cout << "Max Permutation: " << maxPerm << std::endl;
    
   return 0;
}

输出

String: abcbdb
Max Permutation: bbb

方法三:堆算法

  • 实现Heap算法,高效地生成字符串的所有排列。

  • 生成每个排列后,计算大于其相邻字符的字符数量。

  • 保持追踪到目前为止找到的最大计数,并根据需要进行更新。

语法

function generatePermutations(string):
   n = length(string)
   characters = array of n elements initialized with string's characters

   generatePermutationsHelper(n, characters)

function generatePermutationsHelper(n, characters):
   if n = 1:
      checkAndPrintPermutation(characters)
   else:
   for i = 0 to n-1:
      generatePermutationsHelper(n-1, characters)
            
   if n is even:
      swap characters[i] and characters[n-1]
   else:
      swap characters [0] and characters[n-1]

算法

第一步 - 已经初始化了一个数组,用于存储输入字符串的字符。

第 2 步 - 继续创建一个函数,并将其命名为“generatePermutations”,带有两个参数 - 一个最终变量“size”,用于确定数组的大小,以及一个名为“arr”的数组,其中包含字符串字符。

步骤 3 - 如果大小为 1,则通过将数组中的字符组合在一起,直到最大字符数超过连续字符数,打印当前排列。

步骤 4 - 如果不是,则函数返回。为了从索引 0 到 'size - 1' 迭代数组,我们使用一个名为 'i' 的变量。

第 5 步 - 在此迭代中,我们进一步迭代参数大小 - 1 和错误的generatePermutations 函数。

第 6 步 - 如果 size 恰好是奇数,则我们将数组中索引 0 处的元素替换为索引“size - 1”处的元素。

第 7 步 - 类似地,如果 size 结果是偶数,我们将数组中索引“i”处的元素替换为索引“size - 1”。

步骤8 - 最后,我们使用初始数组大小和数组本身作为参数调用"generatePermutations"函数。

示例 1

以下的C++示例使用Heap's算法创建字符串的排列,并识别出在其相邻字符上具有最大字符数的排列 −

为了说明问题,在这个例子中使用"abcd"作为输入字符串。可以修改变量来使用不同的输入字符串。如果排列满足具有比其邻居更多字符的要求,则找到isValidPermutation函数是否有效。generatePermutations函数使用堆栈方法来跟踪具有最多字符的排列,以便它可以生成输入字符串的每个可能的排列。主函数将最大数量和排列本身作为输出打印。

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

// Function to check if the permutation satisfies the condition
bool isValidPermutation(const string& perm) {
   int n = perm.length();
   for (int i = 0; i < n - 1; i++) {
      if (abs(perm[i] - perm[i + 1]) <= 1)
         return false;
   }
   return true;
}

// Function to swap two characters in a string
void swapChar(char& a, char& b) {
   char temp = a;
   a = b;
   b = temp;
}

// Heap's Algorithm for generating permutations
void generatePermutations(string& str, int n, int& maxCount, string& maxPerm, int idx = 0) {
   if (idx == n - 1) {
      if (isValidPermutation(str)) {
         int count = count_if(str.begin(), str.end(), [](char c) {
            return isalpha(c) && c >= 'A' && c <= 'Z';
         });
         if (count > maxCount) {
            maxCount = count;
            maxPerm = str;
         }
      }
      return;
   }

   for (int i = idx; i < n; i++) {
      swapChar(str[idx], str[i]);
      generatePermutations(str, n, maxCount, maxPerm, idx + 1);
      swapChar(str[idx], str[i]);
   }
}

int main() {
   string str = "abcd";
   int n = str.length();
   int maxCount = 0;
   string maxPerm;

   generatePermutations(str, n, maxCount, maxPerm);

   if (maxCount == 0) {
      cout << "No valid permutation found." << endl;
   } else {
      cout << "Maximum number of characters greater than adjacent characters: " << maxCount << endl;
      cout << "Permutation with the maximum count: " << maxPerm << endl;
   }
   return 0;
}

输出

No valid permutation found.

方法4:字典序排序与剪枝

  • 按字典顺序对字符串的字符进行排序。

  • 生成排序字符串的排列。

  • 在每一步中,检查当前排列是否满足最大字符数大于其相邻字符的条件。

  • 如果不是这样,请跳过具有相似前缀的剩余排列,以避免不必要的计算。

语法

  • 生成字符串所有排列的函数

function generatePermutations(string):
  • TODO:排列生成的实现

  • 检查字符是否大于其相邻字符的函数

function isGreaterAdjacent(char1, char2):
  • TODO:比较逻辑的实现

  • 找到具有大于相邻字符的最大数量的排列的函数

function findMaxAdjacentPermutation(string):
  • 生成字符串的所有排列

permutations = generatePermutations(string)
  • 初始化变量

max_permutation = ""
max_count = 0
  • 遍历每个排列

for permutation in permutations:
   count = 0
  • 迭代排列中的每个字符(不包括最后一个字符)

for i from 0 to length(permutation) - 2:
   char1 = permutation[i]
   char2 = permutation[i + 1]
  • 检查当前字符是否大于其相邻字符

if isGreaterAdjacent(char1, char2):
   count = count + 1
  • 检查当前排列的计数是否大于先前的最大值

if count > max_count:
   max_permutation = permutation
   max_count = count
  • 返回具有最大计数的排列

return max_permutation

算法

第一步 - 从输入字符串开始。

第 2 步 - 按字典顺序对字符串进行排序以获得初始排列。

第 3 步 - 将变量 maxCount 初始化为 0,以跟踪大于相邻字符的最大字符数。

第 4 步 - 初始化变量 maxPermutation 以存储最大计数的排列。

第 5 步 - 当有下一个排列时 -

  • 将变量 count 初始化为 0,以跟踪当前大于相邻字符的字符数。

  • 对于当前排列中的每个字符 -

    • 检查当前字符是否大于其前一个字符和后一个字符(如果存在)。

    • 如果满足条件,则将计数增加 1。

  • 如果计数大于最大计数(maxCount)-

    • 将maxCount更新为当前计数。

    • 将 maxPermutation 更新为当前排列。

步骤 6 - 将 maxPermutation 作为结果返回。

示例 1

对于此示例,为简单起见,让我们考虑固定字符串“abcde”。

在这个例子中,countAdjacentGreater函数统计字符串中相邻字符大于其前一个字符的数量。findMaxPermutation函数生成输入字符串的所有排列,并检查每个排列,找出具有最大数量相邻字符大于的那个。

主要函数初始化输入字符串"abcde"和跟踪最大计数和最大排列的变量。它调用findMaxPermutation函数来找到最大排列。

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int countAdjacentGreater(const string& str) {
   int count = 0;
   for (int i = 0; i < str.length() - 1; i++) {
      if (str[i] < str[i + 1]) {
         count++;
      }
   }
   return count;
}

void findMaxPermutation(string& str, int& maxCount, string& maxPerm) {
   sort(str.begin(), str.end());
    
   do {
      int count = countAdjacentGreater(str);
      if (count > maxCount) {
         maxCount = count;
         maxPerm = str;
      }
   } while (next_permutation(str.begin(), str.end()));
}

int main() {
   string str = "abcde";
   int maxCount = 0;
   string maxPerm;

   findMaxPermutation(str, maxCount, maxPerm);

   cout << "String with the maximum number of characters greater than its adjacent characters: " << maxPerm << endl;
   cout << "Count of adjacent characters greater in the maximum permutation: " << maxCount << endl;

   return 0;
}

输出

String with the maximum number of characters greater than its adjacent characters: abcde
Count of adjacent characters greater in the maximum permutation: 4

结论

总之,找到最大字符数大于相邻字符的字符串的排列问题是字符串操作中的一个有趣的挑战。通过分析给定的字符串并有策略地重新排列其字符,可以实现所需的排列。这个问题凸显了在使用字符串和排列时仔细检查和创造性思维的重要性。

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
Article précédent:nombre heptagonalArticle suivant:nombre heptagonal