Maison > développement back-end > C++ > Traduction : Pour les requêtes M, inversez la plage de la chaîne donnée

Traduction : Pour les requêtes M, inversez la plage de la chaîne donnée

王林
Libérer: 2023-08-25 20:09:09
avant
1289 Les gens l'ont consulté

Traduction : Pour les requêtes M, inversez la plage de la chaîne donnée

Dans ce problème, nous effectuerons M requêtes inverses sur la chaîne donnée en fonction des valeurs du tableau.

L'approche naïve pour résoudre le problème consiste à inverser chaque segment de chaîne en fonction de la valeur du tableau donnée.

L'approche optimisée utilise la logique selon laquelle lorsque nous inversons deux fois la même sous-chaîne, nous obtenons la chaîne d'origine.

Énoncé du problème − Nous avons donné une chaîne alpha contenant les caractères alphabétiques. De plus, nous avons donné un tableau arr[] de taille M contenant les entiers positifs. Nous devons effectuer les opérations M sur la chaîne donnée et renvoyer la chaîne finale.

Dans chaque opération, nous devons prendre le arr[i] et vénérer la sous-chaîne arr[i] à N − arr[i] + 1.

示例例子

输入

alpha = "pqrst"; arr = {2, 1};
Copier après la connexion

输出

tqrsp
Copier après la connexion

Explication 

  • 执行第一个查询后,字符串变为 'psrqt'。

  • 执行第二个查询后,我们得到了 'tqrsp'。

输入

−  alpha = "pqrst"; arr = {1, 1};
Copier après la connexion

输出

 − ‘pqrst’
Copier après la connexion

Explication − 如果我们对同一个查询执行偶数次,我们会得到相同的字符串。

输入

 −  alpha = "pqrst"; arr = {1, 1, 1};
Copier après la connexion

输出

 − ‘tsrqp’
Copier après la connexion

Explication − Si nous effectuons la même requête un nombre impair de fois, nous obtenons l'inverse de la chaîne.

Approche 1

Dans cette approche, nous utiliserons la méthode reverse() pour inverser la sous-chaîne. Nous prendrons les pointeurs de début et de fin en utilisant la requête donnée et inverserons la sous-chaîne de la chaîne donnée.

Algorithme

步骤 1 - 开始遍历查询数组。

第2步 - 使用arr[p] - 1初始化'left'变量。

Étape 3 − Initialisez la variable « droite » avec str_len − arr[p] + 1.

Étape 4 - Utilisez la méthode reverse() pour inverser la sous-chaîne du pointeur gauche au pointeur droit.

Exemple

#include <bits/stdc++.h>
using namespace std;

void reverseStrings(string &alpha, int str_len, vector<int> &arr, int arr_len){
    // Traverse all queries
    for (int p = 0; p < arr_len; p++){
        // Get starting pointer
        int left = arr[p] - 1;
        // Ending pointer
        int right = str_len - arr[p] + 1;
        // Reverse the string
        reverse(alpha.begin() + left, alpha.begin() + right);
    }
}
int main(){
    int str_len = 5;
    string alpha = "pqrst";
    int arr_len = 2;
    vector<int> arr = {2, 1};
    reverseStrings(alpha, str_len, arr, arr_len);
    cout << "The string after performing queries is " << alpha << endl;
    return 0;
}
Copier après la connexion

输出

The string after performing queries is tqrsp
Copier après la connexion

Complexité temporelle - O(N*M) pour inverser la sous-chaîne M fois.

Complexité spatiale − O(1) car nous n'utilisons aucun espace dynamique.

方法二

Dans cette approche, nous calculerons cet index particulier et le nombre de fois inclus dans l'inversion à l'aide de requêtes données. Si un index est inclus un nombre pair de fois, nous n’avons pas besoin de l’inverser. Si un index est inclus un nombre impair de fois dans toutes les requêtes données, nous devons inverser le caractère à des index particuliers.

Algorithme

步骤 1 - 初始化长度等于字符串长度的 'cnt' 列表,用 0 存储特定索引在反转中出现的次数。

Étape 2 - Parcourez le tableau de requêtes données et prenez un pointeur gauche et droit de la chaîne en fonction de la requête actuelle.

Étape 3 - Exécutez également la fonction changeRange() pour mettre à jour la liste 'cnt' en fonction des pointeurs gauche et droit de la requête actuelle.

Étape 3.1 - Dans la fonction changeRange(), incrémentez la valeur à l'index « gauche » dans la liste « cnt ».

第3.2步 - "cnt" et "right + 1""指针右侧的所有值。

Ici, nous devions incrémenter toutes les valeurs de la liste « cnt » de 1 dans la plage [gauche, droite]. Ainsi, nous avons incrémenté uniquement cnt[left] de 1 car prendre la somme des préfixes incrémentera toutes les valeurs de 1, ce qui est à droite de l'index « gauche ». De plus, nous ne voulons pas incrémenter les valeurs cnt entre les index [right, str_len], nous l'avons donc déjà décrémenté de 1 car la somme des préfixes l'augmentera de 1.

Étape 4 - Ensuite, exécutez la fonction getPrefixSum() pour calculer la somme des préfixes de la liste « cnt ».

Étape 4.1 - Dans la fonction getPrefixSum(), parcourez la chaîne et ajoutez la valeur de l'élément précédent à l'élément actuel.

步骤 5 - 接下来,以逆序遍历'cnt'列表。如果当前元素是奇数,则将其追加到'tmp'字符串中。

步骤 6 - 用0初始化‘p’ et ‘q’,按照原始顺序遍历‘cnt’列表。

步骤 7 − 如果‘cnt’列表中的当前元素是奇数,则使用tmp[q]更新alpha[p]。

Étape 8 − À la fin, renvoyez la chaîne alpha.

Exemple

的中文翻译为:

示例

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

void changeRange(vector<int>& cnt, int left, int right) {
    // Increase the value of the left index
    cnt[left]++;
    // Decrement value for all indexes after the right index
    if (right + 1 < cnt.size())
        cnt[right + 1]--;
}
void getPrefixSum(vector<int>& cnt) {
    // Calculate prefix sum
    for (int p = 1; p < cnt.size(); p++) {
        cnt[p] += cnt[p - 1];
    }
}
string reverseStrings(string alpha, int str_len, vector<int>& arr, int arr_len) {
    vector<int> cnt(str_len, 0);
    // Traverse the array
    for (int p = 0; p < arr_len; p++) {
        int left = arr[p] <= (str_len + 1) / 2 ? arr[p] - 1 : str_len - arr[p];
        int right = arr[p] <= (str_len + 1) / 2 ? str_len - arr[p] : arr[p] - 1;
        // Changes index ranges between left and right
        changeRange(cnt, left, right);
    }
    getPrefixSum(cnt);
    string tmp;
    // Store characters with the odd reversal in the reverse order in the tmp string
    for (int p = cnt.size() - 1; p >= 0; p--) {
        if (cnt[p] % 2 != 0)
            tmp.push_back(alpha[p]);
    }
    int p = 0, q = 0;
    // For even reversal, pick the character from the original string.
    // For odd reversal, pick the character from the temp string.
    for (p = 0; p < cnt.size(); p++) {
        if (cnt[p] % 2 != 0)
            alpha[p] = tmp[q++];
    }
    // Answer string
    return alpha;
}
int main() {
    int str_len = 5;
    string alpha = "pqrst";
    int arr_len = 2;
    vector<int> arr = { 2, 1 };
    alpha = reverseStrings(alpha, str_len, arr, arr_len);
    cout << "The string after performing queries is: " <<alpha << endl;
    return 0;
}
Copier après la connexion

输出

The string after performing queries is: tqrsp
Copier après la connexion

Complexité temporelle - O(M*N + N), où O(M*N) doit mettre à jour la liste 'cnt' en fonction de la requête, et O(N) doit mettre à jour la chaîne donnée.

空间复杂度 - 使用 'cnt' 列表为 O(N)。

在第一方法中,我们使用了reveres()方法来执行给定字符串上的所有查询。在第二种方法中,我们使用了前缀和技术来计算特定索引在反转中出现的次数。

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!

Étiquettes associées:
source:tutorialspoint.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal