Compter les sous-séquences de caractères entre deux chaînes

Étant donné deux chaînes de caractères source et cible, le défi consiste à déterminer combien de caractères de la chaîne cible peuvent être trouvés dans le même ordre au sein de la chaîne source. En d'autres termes, il faut identifier si la chaîne cible constitue une sous-séquence de source et compter le nombre de correspondances trouvées. Les données d'entrée proviennent du fichier entree.txt et le résultat est записуется dans le fichier sortie.txt.

Format d'entrée

Le fichier entree.txt contient deux lignes distinctes. La première ligne représente la chaîne source et la seconde ligne représente la chaîne cible. Chaque chaîne est composée de caractères imprimables et leur longueur ne dépasse pas 1000 caractères.

Format de sortie

Le fichier sortie.txt contient un entier unique correspondant au nombre de caractères de la chaîne cible qui ont été trouvés dans le même ordre au sein de la chaîne source.

Exemple illustratif

Considérons les chaînes suivantes :


source: abcde
cible: ace

Le résultat obtenu est :


3

Explication de l'exemple

Les caractères a, c et e de la chaîne cible apparaissent dans le même ordre au sein de la chaîne source. Par conséquent, le nombre de correspondances est égal à 3.

Analyse algorithmique

L'algorithme repose sur une approche par balayage séquentiel. On parcourt chaque caractère de la chaîne cible et on cherche sa correspondance dans la chaîne source en commençant à partir de la position où la recherche précédente s'est terminée. Cette technique garantit que l'ordre des caractères est respecté.

Implémentation


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

// Tableaux de caractères pour stocker les chaînes d'entrée
char source[1005], cible[1005];

// Variables pour la gestion de l'algorithme
int positionRecherche, longueurSource, longueurCible, compteur;
int indexSource, indexCible;

int main(){
    // Redirection des flux d'entrée et de sortie vers les fichiers
    freopen("entree.txt", "r", stdin);
    freopen("sortie.txt", "w", stdout);
    
    // Lecture des deux chaînes de caractères
    cin >> source >> cible;
    
    // Calcul des longueurs des chaînes
    longueurSource = strlen(source);
    longueurCible = strlen(cible);
    
    // Initialisation du compteur de correspondances
    compteur = 0;
    
    // Définition du point de départ pour la première recherche
    positionRecherche = 0;
    
    // Parcours de chaque caractère de la chaîne cible
    for(indexCible = 0; indexCible < longueurCible; indexCible++){
        // Recherche du caractère actuel dans la chaîne source
        for(indexSource = positionRecherche; indexSource < longueurSource; indexSource++){
            // Vérification de la correspondance des caractères
            if(cible[indexCible] == source[indexSource]){
                // Mise à jour de la position pour la prochaine recherche
                positionRecherche = indexSource + 1;
                // Incrémentation du compteur de correspondances
                compteur++;
                // Arrêt de la recherche une fois le caractère trouvé
                break;
            }
        }
        
        // Sortie anticipée si aucun caractère correspondant n'est trouvé
        if(indexSource == longueurSource){
            break;
        }
    }
    
    // Affichage du résultat final
    cout << compteur;
    return 0;
}

Déroulement de l'exécution

L'exécution du programme se déroule en plusieurs phases distinctes. Premièrement, les flux d'entrée et de sortie sont redirigés vers les ficihers spécifiés à l'aide de la fonction freopen. Ensuite, les deux chaînes de caractères sont lues depuis le fichier d'entrée et leurs longueurs respectives sont calculées.

La phase principale de l'algorithme consiste à parcourir la chaîne cible caractère par caractère. Pour chaque caractère, on effectue une recherche dans la chaîne source en commençant à la position mémorisée lors de la recherche précédente. Lorsqu'une correspondance est trouvée, la position de recherche est mise à jour pour continuer après le caractère trouvé, et le compteur de correspondances est incrémenté.

Si la recherche dans la chaîne source épuisée toutes les positions possibles sans trouver le caractère actuel de cible, l'algorithme met fin prématurément à la boucle principale, car aucun caractère suivant ne pourra être trouvé.

Analyse de la complexité

Du point de vue de la complexité temporelle, l'algorithme présente une caractéristique de O(m × n), où m représente la longueur de la chaîne cible et n représente la longueur de la chaîne source. Dans le pire des cas, pour chaque caractère de cible, l'algorithme doit parcourir l'intégralité de source.

Concernant la complexité spatiale, l'algorithme utilise O(m + n) d'espace, principalement pour le stockage des deux chaînes de caractères. Les variables supplémantaires occupent un espace constant et négligeable.

Cette appproche, bien que simple, offre une solution directe et compréhensible pour le problème de comptage des sous-séquences. Pour des chaînes de longueur maximale de 1000 caractères, les performances restent tout à fait acceptables dans un contexte de compétition.

Étiquettes: C++ Algorithme chaînes de caractères sous-séquence correspondance séquentielle

Publié le 30 septembre à 06h30