Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Prüfen, wieviele gleiche Zahlen im Edit Feld vorkommt...


bruce185 - Fr 13.02.09 04:05
Titel: Prüfen, wieviele gleiche Zahlen im Edit Feld vorkommt...
Hallo,
ich habe hier im Forum schon gesucht, aber nix brachbares zu meinem Problem gefunden.
Ich möchte von einem Edit Feld prüfen, wieviele gleiche Zahlen vorhanden sind, getrennt von einem Plus Zeichen.

Beispiel:
1+1+1+2+2+3+1+4+8+2+10+20+128+111+23

und in Memo1 möchte ich, dass es so in dieser art eingetragen wird:
Die Zahl 1 kommt 4 mal vor.
Die Zahl 2 kommt 3 mal vor.
Die Zahl 3 kommt 1 mal vor.
Die Zahl 4 kommt 1 mal vor.
Die Zahl 8 kommt 1 mal vor.
Die Zahl 10 kommt 1 mal vor.
Die Zahl 20 kommt 1 mal vor.
Die Zahl 128 kommt 1 mal vor.
Die Zahl 111 kommt 1 mal vor.
Die Zahl 23 kommt 1 mal vor.
usw.

Wenn ich z.B. Prüfen möchte, wie oft die 1 vorkommt, dann werden auch alle 1er zusammen gezählt, das möchte ich aber nicht, deshalb habe ich ein Plus Zeichen benutzt, um die Zahlen von einander zu trennen.

Ich bedanke mich schonmal für die Hilfe.

MfG


jaenicke - Fr 13.02.09 05:05

In welchem Bereich liegen die Zahlen denn? Wenn dieser beschränkt und relativ klein ist, dann wäre ein Array zum zählen eine einfache Möglichkeit.

Wenn du es dir einfach machen willst und die Geschwindigkeit und Sauberkeit der Lösung nicht so wichtig ist, dann wäre die einfachste Lösung:
Nimm eine TStringList, stell deren Delimiter auf das '+' und pack den Inhalt des Edits in DelimitedText. Danach gehst du die Zeilen durch, in jeder steht eine einzelne Zahl.

In einer zweiten StringList speicherst du die Anzahl der Zahlen. Ist die Zahl bereits vorhanden, dann erhöhst du deren Objects-Pointer um 1, diesen kannst du einfach als Integerwert benutzen. Ist sie noch nicht vorhanden, dann fügst du sie mit AddObject hinzu.

Delphi-Quelltext
1:
2:
3:
4:
        if tmp >= 0 then
          NumCountStringList.Objects[tmp] := TObject(Integer(NumCountStringList.Objects[tmp]) + 1)
        else
          NumCountStringList.AddObject(AktuelleZahlAlsString, TObject(1));
tmp ist hier das Ergebnis der Suche nach der Zahl in der zweiten StringList (NumCountStringList).


wazap - Fr 13.02.09 06:42

Ehrlich gesagt, ein blöderen Lösungsweg fand ich echt nicht ^^ - Aber es funktioniert!!


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
function MyFunction(const sText: string): TStringList;
var
  Count: array of Integer;
  List1, List2: TStringList;
  I, Q, Index: Integer;
  Number: string;
begin
  List1 := TStringList.Create;
  List2 := TStringList.Create;
  Result := TStringList.Create;

  List1.Delimiter := '+';
  List1.DelimitedText := sText;

  SetLength(Count, List1.Count);

  for I := 0 to List1.Count - 1 do
  begin
    Number := List1[I];
    Index := -1;

    for Q := 0 to List2.Count - 1 do
    begin
      if List2[Q] = Number then
      begin
        Index := Q;
        Break;
      end;
    end;

    if Index > -1 then
      Inc(Count[Index])
    else List2.Add(Number);
  end;

  for I := 0 to List2.Count - 1 do
    Result.Add(Format('Die Zahl %s kommt %d mal vor!', [List2[I], Count[I]+1]));
end;


bruce185 - Fr 13.02.09 09:01

Danke euch für die antworten.

Ich habe den Code von @wazap in meinem Projekt eingebaut und erweitert, funktioniert bestens.

Ihr habt mir sehr Weitergeholfen.

Vielen Dank.

MfG


Jakob_Ullmann - Fr 13.02.09 14:24

Ich hätte noch eine andere Lösung:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function HowManyN(s: string; LookFor: Integer): Integer;
var
  i, j: Integer;
  LookForS: string;
begin
  s := '+' + s + '+';
  LookForS := '+' + IntToStr(LookFor) + '+';
  j := 0;
  for i := 1 to Length(s) - Length(LookForS) + 1 do
    if Copy(s, i, Length(LookForS)) = LookForS then
      inc(j);
  Result := j;
end;


edit zum Testen:


Delphi-Quelltext
1:
ShowMessage(IntToStr(HowManyN('1+2+3+1+1+2+1'1)));                    


Gibt das richtige Ergebnis 4 aus.


jaenicke - Fr 13.02.09 15:40

user profile iconwazap hat folgendes geschrieben Zum zitierten Posting springen:
Aber es funktioniert!!
[..]
Ein weiteres Array braucht man ja gar nicht. Ich hatte das so gemacht und gemeint: ;-)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, tmp: Integer;
  Numbers, NumCount: TStringList;
begin
  NumCount := TStringList.Create;
  try
    Numbers := TStringList.Create;
    try
      Numbers.Delimiter := '+';
      Numbers.DelimitedText := Edit1.Text;
      for i := 0 to Numbers.Count - 1 do
      begin
        tmp := NumCount.IndexOf(Numbers[i]);
        if tmp >= 0 then
          NumCount.Objects[tmp] := TObject(Integer(NumCount.Objects[tmp]) + 1)
        else
          NumCount.AddObject(Numbers[i], TObject(1));
      end;
    finally
      Numbers.Free;
    end;
    for i := 0 to NumCount.Count - 1 do
      Memo1.Lines.Add(NumCount[i] + ' - ' + IntToStr(Integer(NumCount.Objects[i])));
  finally
    NumCount.Free;
  end;
end;


Jakob_Ullmann - Fr 13.02.09 16:39

In dem Fall wird doch überhaupt kein Array gebraucht. Höchstens, wenn er auch wissen will, wo sich die Zahlen befinden. :wink:


jaenicke - Fr 13.02.09 16:44

Naja, aber jede Zahl einzeln abzufragen und jedesmal den String zu durchsuchen ist wenig effizient. Man kann sich auch gleich alle Zahlen merken beim ersten Durchlauf. ;-)