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

boxma Messages postés 6 Date d'inscription dimanche 3 octobre 2010 Statut Membre Dernière intervention 5 février 2011
8 déc. 2010 à 14:59
Bonjour;
le cas :
00__00__00__00__00__00

a mon avis on change carrement de sujet vue que dans ce cas on parle d'ensemble de goutes constantes

pour moi c'est simple ce cas n'est pas constant .

pour résumer je te conseil des faire ce qu'on appel un intervalle de référence

function GetFirst0(text: string): Byte;
var
  I: byte;
begin
  for I := 1 to Length(text) do
    if Text[i] = '0' then
    begin
     Result := i;
     exit
    end;
end;

function GetLast0(text: string): Byte;
var
  I: Byte;
begin
  for I := Length(text) downto 1 do
   if text[i] = '0' then
   begin
     result := i;
     exit
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  I: Byte;
  Pinterval: Byte;
  interval: Byte;
  count0: Byte;
begin
  for I := GetFirst0(Edit1.Text) to GetLast0(Edit1.Text) do
  begin
    if Edit1.Text[i] = '0' then
    begin
      inc(Count0);
      if Count0 = 2 then Pinterval := interval
      else if interval <> Pinterval then
           begin
             ShowMessage('irregulier');
             Exit
           end;
      interval := 0
    end
    else inc(interval);
  end;
  ShowMessage('Regulier');
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in ['_','0',#8]) then key := #0
end;


il faudra juste joué avec la valeur 2 de la ligne
if Count0 = 2 then Pinterval := interval  


ps: je ne suis pas sur du résultat j'ai pas delphi sur cette machine
3
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 déc. 2010 à 01:00
Bonjour quand même,

« [i]j'aimerai trouver une fonction qui me signale quand mon 'robinet' fuit de maniere
constante /i»

On trouve de drôles de trucs sur le site mais, franchement, il y a peu de chances qu'un développeur ait déjà publié une telle fonction (je ne vois que Francky... Et encore! Il s'intéresse plus aux gaz qu'aux liquides).

Tu peux toujours regarder dans l'Aide Delphi à la rubrique 'Pos'.
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 déc. 2010 à 01:07
... et même 'PosEx' (c'est mieux pour les fuites).
0
Utilisateur anonyme
8 déc. 2010 à 08:34
« j'aimerai trouver une fonction qui me signale quand mon 'robinet' fuit de maniere
constante » je ne vois que Francky... Et encore! Il s'intéresse plus aux gaz qu'aux liquides

je ne vois que Francky=> Bah alors mon Cari, un expert comme toi du bitoniau, une ptite fuite ca devrait pas te poser problème ;)

Plus objectivement je procéderais ainsi, je créerais une fonction qui
1)Lirais chacun des caractères de ta string.
2)Si le caractère lu est 0, alors il suffit de diviser sa position dans la string par la position du premier 0 non nulle, que tu as eu.
Si le reste est nul alors tu renvoies true sinon tu renvoies False.

C'est tout simple non ?
0

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

Posez votre question
Utilisateur anonyme
8 déc. 2010 à 12:44
oui scusez! bonjour d'abord..
interressant ta facon de voir francky,
je supose que tu voulais dire si le reste = 1..


AlcAt
0
Utilisateur anonyme
8 déc. 2010 à 12:48
par contre ca marche pour ca 0___0___0___0
effectivement
mais pas pour ca
00__00__00__00__00__00
et encore moins pour ca...
0__0___0__0___0__0___0__0___0__0

AlcAt
0
Utilisateur anonyme
8 déc. 2010 à 15:25
Effectivement Boxma les 2 exemples donnés par alcat ne correspond pas à une fuite constante

@alcat : Non le reste doit être nul et non égal à 1. Rappel d'une division euclidienne : N=D*Q+R.
0
Utilisateur anonyme
8 déc. 2010 à 15:30
merci boxma! j'vais essayer ca tonight...

vous etes super cool!


AlcAt
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 déc. 2010 à 18:47
La fonction suivante semble fonctionner.
Si la fonction renvoie -1, la suite n'est pas périodique. Sinon, la fonction renvoie la période:

uses  StrUtils;

function IsPeriodic(S: string): Integer;
  var    Count,Index: Integer;
         SubStr: string;
  begin
  Result := -1;
  for Count := 2 to Length(S) div 2 do begin
    for Index := 1 to Length(S) div 2 do begin
      SubStr:= Copy(S,Index,Count);
      if (PosEx(SubStr,S,Index+Count)=Index+Count)
         and (PosEx(SubStr,S,Index+Count+Count)=Index+Count+Count)
         then begin
     	  result := Count;
      	  exit;
   	end;
     end;
   end;
end;
0
boxma Messages postés 6 Date d'inscription dimanche 3 octobre 2010 Statut Membre Dernière intervention 5 février 2011
8 déc. 2010 à 19:14
Bonsoir,
@Caribensila
j'avoue que je n'est pas bien ton compris code
ça seré sympa d'ajouter quelque détail

surtt sur le point suivant:

les 2 boucles imbrique
for Count := 2 to Length(S) div 2 do begin
    for Index := 1 to Length(S) div 2 do begin



Merci
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 déc. 2010 à 19:34
SubStr est la sous-chaîne dont tu recherches les occurences dans la suite. Mais elle peut commencer n'importe où dans la string et on ne connaît pas sa longueur a priori...

Pour comprendre les 2 boucles imbriquées, le mieux est que tu places un TMemo (avec une ScrollBar verticale) sur ta fiche, puis que tu ajoutes :

Form1.Memo1.Lines.Add(SubStr);


après

SubStr:= Copy(S,Index,Count);


Ca te semblera plus clair...
0
Utilisateur anonyme
8 déc. 2010 à 19:35
merci Caribensila

pour ce code de genie!
ca marche nikel...
AlcAt
0
Caribensila Messages postés 2527 Date d'inscription jeudi 15 janvier 2004 Statut Membre Dernière intervention 16 octobre 2019 18
8 déc. 2010 à 19:44
Merci à toi.

Mais ce n'est pas un code de génie car la fonction peut s'arrêter à une sous-période et laisser passer une période plus longue...

Le mieux serait quand même de changer le joint du robinet...
0
boxma Messages postés 6 Date d'inscription dimanche 3 octobre 2010 Statut Membre Dernière intervention 5 février 2011
8 déc. 2010 à 22:05
rebonsoir
merci la rapidité de ta repense Caribensila
0
cs_yanb Messages postés 271 Date d'inscription lundi 27 octobre 2003 Statut Membre Dernière intervention 7 juillet 2022 14
9 déc. 2010 à 14:20
Salut,
intéressant comme problème les fuites, les gouttes, les joints, les robinets, les bitoniaux ...
donc voilà régularité ou constante... je suis parti dans un truc un peu différent de caribensila, une trame qui contient peut-être une constante exemple:
0_0_0_0_0_0_0 => constante 0_
00_00_00_00_00 => constante 00_
0_00_0_00_0_00_ => constante 0_00_
0_00__0_000_0_00__0_000_0_00__0_000_ => constante 0_00__0_000_
0_00__0___0__0_0_0_0_0__000__0_0 => pas constante
Ceci est un exemple des constantes retrouvés avec le bout de code suivant
Par contre j'ai pas véritablement testé à fond, c'est juste un exemple que tu peux améliorer et optimiser.
Ps : dans le code j'ai ajouté un tableau de constante prédéfini donc... ainsi que l'information d'une nouvelle constante donc...
uses StrUtils;

const
    TabC : array [0..2] of string = ('0__','00__','0_0__');

var
    Tab : array of string;

function Search(Value: string): Boolean;
var
  I     : Integer;
  N     : Integer;
  V     : Integer;
  J     : Integer;
  NewV  : string;
begin
    Result := True;
    N := Length(Value);
    for I := 0 to High(Tab) do
    begin
        V := Length(Tab[I]);
        NewV := Value;
        for J := 1 to Trunc(N div V) do
        begin
            if Pos(Tab[I], NewV) = 1 then
            begin
                Result := False;
                NewV := Copy(NewV, V+1, N);
            end
            else
            begin
                Result := True;
                Break;
            end;
        end;
        if not Result then
        begin
            if Length(NewV) <= 1 then
            begin
                if I = High(Tab) then
                    MessageDlg('Nouvelle sorte de Constante '+Tab[I], mtInformation, [mbOK], 0);
                Break;
            end
            else
                Result := True;
        end;
    end;
end;

procedure List0_(Value, SubStr1, SubStr2: string; List1, List2: TStringList; Trie: Boolean);
var
    A       : Integer;
    B       : Integer;
    SubStr  : string;
begin
    List1.Clear;
    List1.Sorted := Trie;
    List1.Duplicates := dupIgnore;
    List2.Clear;
    List2.Sorted := Trie;
    List2.Duplicates := dupIgnore;
    SubStr := Value;
    while (Pos(SubStr1, Substr) <> 0)and (Pos(SubStr2, Substr) <> 0)  do
    begin
        A := Pos(SubStr1, Substr);
        B := PosEx(SubStr2, Substr, A);
        List1.Add(Copy(Substr, A-1, B-1));
        Substr := Copy(Substr, B, Length(SubStr));
        A := Pos(SubStr1, Substr);
        if A <> 0 then
            List2.Add(Copy(Substr, 0, A-1));
        Substr := Copy(Substr, A, Length(SubStr));
    end;
end;

function SearchReg(Value: string): string;
var
    I       : Integer;
    C       : Integer;
    D       : Integer;
    List0   : TStringList;
    List_   : TStringList;
    SubStr  : string;
    SubStr1 : string;
    SubStr2 : string;
begin
    List0 := TStringList.Create;
    List_ := TStringList.Create;
    try
        if Pos('0',Value) = 1 then
        begin
            SubStr1 := '0';
            SubStr2 := '_';
        end
        else
        begin
            SubStr1 := '_';
            SubStr2 := '0';
        end;
        SubStr := Value;
        List0_(Value, SubStr1, SubStr2, List0, List_, True);
        C := List0.Count;
        D := List_.Count;
        List0_(Value, SubStr1, SubStr2, List0, List_, False);
        if D > C then
            C := D;
        SubStr := EmptyStr;
        for I := 0 to C - 1 do
            SubStr := SubStr + List0[I] + List_[I];
        Result := SubStr;
    finally
        List0.Free;
        List_.Free;
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
    I : Integer;
begin
    SetLength(Tab, High(TabC)+ 2);
    Tab[High(Tab)] := SearchReg(Edit1.Text);
    for I := 0 to High(TabC) do
        Tab[I] := TabC[I];
    if Search(Edit1.Text)then
        ShowMessage('Irrégulier')
    else
        ShowMessage('Régulier');
end;

@+Yanb
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 à 15:50
Haaa mais tout dépend de la fuite!
ici au Portugal on a des fuites de ce genre là:
_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______________________________________

En plus, vous vous compliquez trop la vie pour une fuite d' eau, alors, de gaz, je n' ose même pas imaginer!!!

Je pense qu' il nous manque donc un paramètre important qui est la quantité maximum de gouttes/non gouttes pour la séquence qui se répète:

function Recherche_Sequence_la_plus_grande(Fuite: String; MaxSequence: Integer): String;

// Cette sous-fonction vérifie que cette séquence se répète dans la fuite :)
function SequenceValide(UneSequence: String): 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(UneSequence, Reste_a_analyser);
PosOk := posSequence <> 0;

while posOk do
begin
Delete(Reste_a_analyser, posSequence, length(UneSequence));
posSequence := pos(UneSequence, Reste_a_analyser);
posOk :p 1;
end;

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

var
i, s: Integer;
EtudierSequence: String;
begin
Result := '';

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

if SequenceValide(EtudierSequence)
then
if Length(EtudierSequence) > Length(Result)
then Result := EtudierSequence;
end;
end;

la fonction peut très bien être appelée comme ça:
SequenceTrouvee := Recherche_Sequence_la_plus_grande(Fuite, Length(fuite));

Voilà,

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 à 15:53
Arg, je reposte car j' avais bien indenté:

function Recherche_Sequence_la_plus_grande(Fuite: String; MaxSequence: Integer): String;

    // Cette sous-fonction vérifie que cette séquence se répète dans la fuite :) 
    function SequenceValide(UneSequence: String): 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(UneSequence, Reste_a_analyser);
      PosOk := posSequence <> 0;

      while posOk do 
      begin
        Delete(Reste_a_analyser, posSequence, length(UneSequence));
        posSequence := pos(UneSequence, Reste_a_analyser);
        posOk :p 1;
      end;

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

var 
  i, s: Integer;
  EtudierSequence: String;
begin
  Result := '';

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

     if SequenceValide(EtudierSequence)
     then 
       if Length(EtudierSequence) > Length(Result)
       then Result := EtudierSequence;
   end;
end;
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:00
Cette fois j' ai testé et ça marche impecc' :

procedure Tform1.cySpeedButton2Click(Sender: TObject);

    function Recherche_Sequence_la_plus_petite(Fuite: String; MaxSequence: Integer): String;

        // Cette sous-fonction vérifie que cette séquence se répète dans la fuite :)
        function SequenceValide(UneSequence: String): 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(UneSequence, Reste_a_analyser);
          PosOk := posSequence <> 0;

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

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

    var
      i, s: Integer;
      EtudierSequence: String;
    begin
      Result := '';

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

         if SequenceValide(EtudierSequence)
         then
           if (Result = '') or (Length(EtudierSequence) < Length(Result))
           then Result := EtudierSequence;
       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));
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:06
'_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______________________________________';


...
Ce ne serait pas une fuite de chasse d'eau, ça ?
0
Utilisateur anonyme
9 déc. 2010 à 16:18
whaou!j'en reste baba...je vais tester des que je trouve le temps!
respect!!!

AlcAt
0
Rejoignez-nous