Manipulation de string

Résolu
Utilisateur anonyme - 7 déc. 2010 à 22:00
 Utilisateur anonyme - 12 déc. 2010 à 03:36
j'ai un string du style:

0___0_0____0___00_____0________0__


'O' -> la goutte est tombée
'_' -> la goutte n' est pas tombée


et j'aimerai trouver une fonction qui me signale quand mon 'robinet' fuit de maniere
constante :

0___0___0___0___0___0___0___0

ou encore:
00_____00_____00_____00_____


voila ..dur! dur! et merci a ceux qui pouront m'aider!

AlcAt

50 réponses

cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 16:22
@Cari: code testé d' après le pipi de mon chien.

Code optimisé pour sa rapidité (version finale):

procedure Tform1.cySpeedButton2Click(Sender: TObject);

    function Recherche_Sequence_la_plus_petite(Fuite: String; MaxSequence: Integer): String;
    var
      EtudierSequence: String;
      LengthResult, lengthEtudierSequence: Integer;
      i, s: Integer;

        // Cette sous-fonction vérifie que EtudierSequence se répète dans la fuite :)
        function SequenceValide: Boolean;
        var
          posSequence: Integer;
          Reste_a_analyser: String;
          PosOk: Boolean;
        begin
          Reste_a_analyser := fuite;

          // Recherche de la 1ere occurence de la séquence:
          posSequence := pos(EtudierSequence, Reste_a_analyser);
          PosOk := posSequence <> 0;

          while posOk do
          begin
            Delete(Reste_a_analyser, posSequence, lengthEtudierSequence);
            posSequence := pos(EtudierSequence, Reste_a_analyser);
            posOk :posSequence 1;
          end;

          Result := length(Reste_a_analyser) < lengthEtudierSequence; // La séquence s' est bien répétée jusqu' à la fin ...
        end;

    begin
      Result := '';
      LengthResult := 0;

     for i := 1 to length(Fuite) do
       for s:= 1 to MaxSequence do
       begin
         EtudierSequence := Copy(Fuite, i, s);
         lengthEtudierSequence := length(EtudierSequence);

         if (LengthResult = 0) or (lengthEtudierSequence < LengthResult)  // ne sera pas plus petite ...
         then
           if SequenceValide
           then begin
             Result := EtudierSequence;
             LengthResult := lengthEtudierSequence;
           end;
       end;
    end;

var fuga: String;
begin
  fuga := '_0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________';

  cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga));

  if (cySpeedButton2.Caption Fuga) or (cySpeedButton2.Caption '')
  then ShowMessage('Pas de séquence trouvée!');
end;




Composants Cindy pour Delphi
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 16:43
@Mauricio,

Ton code reconnaît une "Sequence" inattendue dans ce string :

fuga := '_0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00___0___________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00___0___________________________________';


L'affaire est plus ardue qu'il n'y paraît...
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 16:47
Oui, c' est normal: elle renvoie toute la string: donc une séquence répétée une fois :)
soit: Resultat = Fuga

c' est pour cela que je fais cela:
if (cySpeedButton2.Caption Fuga) or (cySpeedButton2.Caption '')
then ShowMessage('Pas de séquence trouvée!');


Composants Cindy pour Delphi
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 16:48
Pour éviter cela, tu peux aussi appeler la fonction de manière suivante (en faisant -1):
cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga)-1);



Composants Cindy pour Delphi
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 16:49
Oublie mon dernier post, c' est n' importe quoi :)


Composants Cindy pour Delphi
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 17:15
@cari: j' ai trouvé l' erreur et une autre. Je corrige et je poste...


Composants Cindy pour Delphi
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 18:21
Cette fois ça marche impecc'

@Cari: a noter que je divise par 2 ici:
cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga) div 2);
pour renvoyer un résultat oú la séquence se répète au moins 2 fois en entier.

Pour un résultat oú la séquence n' a pas besoin de se répéter 2 fois en entier, faites ainsi:
cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga) div 2);

Soit cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite('_000_00_000_', );


procedure Tform1.cySpeedButton2Click(Sender: TObject);

    function Recherche_Sequence_la_plus_petite(Fuite: String; MaxSequence: Integer): String;
    var
      EtudierSequence: String;
      LengthFuite, LengthResult, lengthEtudierSequence: Integer;
      i, s: Integer;

        // Cette sous-fonction vérifie que EtudierSequence se répète dans la fuite :)
        function SequenceValide: Boolean;
        var
          posSequence: Integer;
          Reste_a_analyser: String;
        begin
          Reste_a_analyser := fuite;

          // Recherche de la 1ere occurence de la séquence:
          posSequence := pos(EtudierSequence, Reste_a_analyser);

          if posSequence > 1   // La séquence ne commence pas exactement au début de la fuite!
          then
            // Vérifier si ce qui est avant le début de la 1ère séquence correspond à la fin de celle-ci ...
            if posSequence-1 < lengthEtudierSequence
            then
              if copy(Reste_a_analyser, 1, posSequence-1) = copy(EtudierSequence, lengthEtudierSequence - (posSequence - 2), posSequence-1)
              then begin
                Delete(Reste_a_analyser, 1, posSequence - 1);
                posSequence := 1;
              end;

          while posSequence = 1 do
          begin
            Delete(Reste_a_analyser, posSequence, lengthEtudierSequence);
            posSequence := pos(EtudierSequence, Reste_a_analyser);
          end;

          if Reste_a_analyser = ''
          then Result := true
          else Result :pos(Reste_a_analyser, EtudierSequence) 1;  // Dernière séquence qui n' est pas en entier
        end;

    begin
      Result := '';
      LengthResult := 0;
      LengthFuite := Length(Fuite);

      // Eviter de renvoyer toute la string comme séquence :
      if MaxSequence > LengthFuite - 1
      then MaxSequence := LengthFuite - 1;

      for i := 1 to lengthFuite do
        for s:= 1 to MaxSequence do
        begin
          EtudierSequence := Copy(Fuite, i, s);
          lengthEtudierSequence := length(EtudierSequence);

          if (LengthResult = 0) or (lengthEtudierSequence < LengthResult)  // Séquence plus petite ...
          then
            if SequenceValide
            then begin
              Result := EtudierSequence;
              LengthResult := lengthEtudierSequence;
            end;
        end;
    end;

var fuga: String;
begin
  fuga := '_0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________';

  // On divise par 2 pour avoir un résultat avec au moins 2 séquences entières, (sinon, on peut avoir une occurence entière suivi d' une partie de la suivante) ...
  cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga) div 2);

  if cySpeedButton2.Caption = ''
  then ShowMessage('Pas de séquence trouvée!');
end;


Composants Cindy pour Delphi
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 18:23
Et encore, je me complique la vie ici:

if posSequence > 1 // La séquence ne commence pas exactement au début de la fuite!
then
// Vérifier si ce qui est avant le début de la 1ère séquence correspond à la fin de celle-ci ...
if posSequence-1 < lengthEtudierSequence
then
if copy(Reste_a_analyser, 1, posSequence-1) = copy(EtudierSequence, lengthEtudierSequence - (posSequence - 2), posSequence-1)
then begin
Delete(Reste_a_analyser, 1, posSequence - 1);
posSequence := 1;
end;

Car il y a encore moyen de faire plus simple!
En effet, le début de "Fuite" possède TOUJOURS le début de la séquence!
Je fais un test et je poste juste après ...

Composants Cindy pour Delphi
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 18:33
« En effet, le début de "Fuite" possède TOUJOURS le début de la séquence! »

Ca dépend... On peut imaginer un écoulement chaotique qui devient périodique à un instant t ...

'_0__0_00___0_0_0_0_0_0_0'

'faut voir le cahier des charges du plombier... :)
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 18:34
Voilà,

je ne pense pas que l' on puisse faire plus simple ...
Disons que finalement je me suis bien compliqué au début :) le code n' est toutefois pas très différent:

procedure Tform1.cySpeedButton2Click(Sender: TObject);

    function Recherche_Sequence_la_plus_petite(Fuite: String; MaxSequence: Integer): String;
    var
      EtudierSequence: String;
      LengthFuite, LengthResult, lengthEtudierSequence: Integer;

        // Cette sous-fonction vérifie que EtudierSequence se répète dans toute la fuite :
        function SequenceValide: Boolean;
        var
          posSequence: Integer;
          Reste_a_analyser: String;
        begin
          Reste_a_analyser := fuite;

          // 1ere occurence de la séquence de EtudierSequence toujours à la position 1 :
          while pos(EtudierSequence, Reste_a_analyser) = 1 do
            Delete(Reste_a_analyser, 1, lengthEtudierSequence);

          if Reste_a_analyser = ''
          then Result := true
          else Result :pos(Reste_a_analyser, EtudierSequence) 1;  // Dernière séquence qui n' est pas en entier
        end;

    begin
      Result := '';
      LengthResult := 0;
      LengthFuite := Length(Fuite);

      // Eviter de renvoyer toute la string comme séquence :
      if MaxSequence > LengthFuite - 1
      then MaxSequence := LengthFuite - 1;

      for lengthEtudierSequence := 1 to MaxSequence do
      begin
        EtudierSequence := Copy(Fuite, 1, lengthEtudierSequence);

        if (LengthResult = 0) or (lengthEtudierSequence < LengthResult)  // Séquence plus petite ...
        then
          if SequenceValide
          then begin
            Result := EtudierSequence;
            LengthResult := lengthEtudierSequence;
          end;
      end;
    end;

var fuga: String;
begin
  fuga := '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
          '0000000000_0000000_0000_00_0_________000000000000_00______________________________________';

  // On divise par 2 pour avoir un résultat avec au moins 2 séquences entières, (sinon, on peut avoir une occurence entière suivi d' une partie de la suivante) ...
  cySpeedButton2.Caption := Recherche_Sequence_la_plus_petite(Fuga, length(fuga) div 2);

  if cySpeedButton2.Caption = ''
  then ShowMessage('Pas de séquence trouvée!');
end;


Composants Cindy pour Delphi
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 18:39
Moi aussi, j'ai divisé par deux. Mais je ne pense pas que ce soit la bonne méthode.
En effet, tout dépend de la longueur de la séquence...
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 18:39
«Ca dépend... On peut imaginer un écoulement chaotique qui devient périodique à un instant t ...

'_0__0_00___0_0_0_0_0_0_0'

'faut voir le cahier des charges du plombier... :)»


Oui, j' étais parti dans cette idée là aussi mais ça ne semble pas être le cas ...

Si ça l' est, il faut faire comme ça :
        function SequenceValide: Boolean;
        var
          posSequence: Integer;
          Reste_a_analyser: String;
        begin
          Reste_a_analyser := fuite;

          // Recherche de la 1ere occurence de la séquence:
          posSequence := pos(EtudierSequence, Reste_a_analyser);

          if posSequence > 1   // La séquence ne commence pas exactement au début de la fuite!
          then begin
            Delete(Reste_a_analyser, 1, posSequence - 1);
            posSequence := 1;
          end;

          while posSequence = 1 do
          begin
            Delete(Reste_a_analyser, posSequence, lengthEtudierSequence);
            posSequence := pos(EtudierSequence, Reste_a_analyser);
          end;

          if Reste_a_analyser = ''
          then Result := true
          else Result :pos(Reste_a_analyser, EtudierSequence) 1;  // Dernière séquence qui n' est pas en entier
        end;



Composants Cindy pour Delphi
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 18:51
ERRATUM: remplacer MaxSequence par MaxLengthSequence dans mon code pour meilleure comprehension!

«@Mauricio,
Ton code reconnaît une "Sequence" inattendue dans ce string :
fuga := '_0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
'0000000000_0000000_0000_00_0_________000000000000_00______________________________________' +
'0000000000_0000000_0000_00_0_________000000000000_00___0___________________________________' +
'0000000000_0000000_0000_00_0_________000000000000_00___0___________________________________';
L'affaire est plus ardue qu'il n'y paraît... »


Ba forcément, si on divise pas par 2 (on permet moins de 2 séquences entières), on a donc 2 séquences:
- Une séquence entière (= "fuga" moins le dernier caractère, car on répète à partir de celui-ci)
- Une séquence juste avec le 1er caractère de la séquence qui est '_' !!!



«Moi aussi, j'ai divisé par deux. Mais je ne pense pas que ce soit la bonne méthode.
En effet, tout dépend de la longueur de la séquence...»

Tout dépend donc de l' utilisation que l' on veut faire mais en tout cas ça ne dépend pas de la longueur de la séquence mais bien du nombre d' occurences entières minimum permises une ou 2 voire plus! d' ou le paramètre "MaxLengthSequence" dans ma fonction ...

A+


Composants Cindy pour Delphi
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 19:01
Euh... Tout dépend des besoins du plombier.
Moi, je vais attendre son avis.
Y'a des bonnes idées dans toutes les propositions, mais tant qu'on est pas fixés, on perd un peu notre temps.

Parce qu'ici, on fait une analyse de la string a posteriori, mais si ça doit se faire en real time, ça change tout.
0
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 déc. 2010 à 19:05
à mon avis, il est parti se coucher, on lui a donné mal à la tête


Composants Cindy pour Delphi
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 19:14
... En tout cas, nous, on a de la flotte fraîche pour le pastis.
0
Utilisateur anonyme
9 déc. 2010 à 19:17
nan nan j'suis la..

«Ca dépend... On peut imaginer un écoulement chaotique qui devient périodique à un instant t ...

'_0__0_00___0_0_0_0_0_0_0'

c'est exactement ca..

mon string se lit de droite a gauche:

mon robinet fuit de maniere chaotique
___00_0___0___0____0_0_00__0
puis tout a coup devient regulier
?_0_0_0_0___00_0___0___0____0_0_00__0

au point d'interrogation, je supose que la goutte d'eau va tomber...
alors je met mon sceau pour la recuperer

AlcAt
0
Utilisateur anonyme
9 déc. 2010 à 19:33
en tous cas un grand grand merci a tous les 2...

franchement je vous arrive pas a la cheville en programation..

ca déchire!!

AlcAt
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 19:33
Et ben voilà. Mais ça change tout !

Perso, je ferais plutôt comme ça, déjà :

_0__0_00_0___000_0__0__0__0__0?

Parce que l'opération serait plus facile à simuler avec une string.
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
9 déc. 2010 à 20:01
... Non! J'ai dit une connerie. C'est peut-être mieux comme ça :

?_00_00_00_0_0__0__0
0
Rejoignez-nous