Porównanie wartości editów i szukanie duplikatów

0

Chciałbym porównać 10 pól edycyjnych i jeżeli liczba powtórzy się w którymś z nich to wyskakuje wiadomość.
Sam napisałem coś takiego kompiluje się wszystko lecz nie działa


if strtoint(edit1.text)=strtoint(edit2.text) or strtoint(edit3.Text) or strtoint(edit4.text) or  strtoint(edit5.text)  or strtoint(edit6.text) or strtoint(edit7.text) or strtoint(edit8.text) or strtoint(edit9.text) or strtoint(edit10.text)
then
showmessage('Wpisales dwa razy lub wiecej ta sama liczbe!')

Proszę o pomoc!

1

Jeśli miałbyś 100 editów (w sumie dziwny pomysł, ale co tam) to też byś napisał takiego if'a? Zapisz te liczby z editów do tablicy 10 elementowej (możesz to zrobić za pomocą pętli + http://docwiki.embarcadero.com/CodeExamples/Seattle/en/FindComponent_%28Delphi%29 ), posortuj a następnie sprawdź (w pętli) czy dwa sąsiadujące ze sobą elementy nie są takie same.

0

Ale mi pomogłeś,może poczekam na odpowiedź kogoś bardziej ogarniętego.
wolfik ..

Po co mi robić tablicę dla 10 elementów i bawić się w tablice...

2

@Mr.YaHooo dobrze podpowiedział - żeby kod wyglądał i działał sensownie, użyj np. tablicy, wpakuj tam wyniki konwersji treści pól edycyjnych i wtedy na spokojnie szukaj powtórek; Możesz się obejść bez konwersji i po prostu porównywać tekst, jednak to zależy od Twoich oczekiwań;

Wracając do problemu - kod nie działa właściwie, bo tak go zapisałeś; Pierwszy argument warunku to porównanie, reszta to wykonywanie alternatywy na zwróconym wyniku z porównania; I niby jak to ma szukać powtórzeń?

Po co mi robić tablicę dla 10 elementów i bawić się w tablice...

Skoro jesteś mądrzejszy i wiesz lepiej, to dlaczego założyłeś wątek i prosisz o pomoc?

1

Po co mi robić tablicę dla 10 elementów i bawić się w tablice...
Dokładnie jak @furious programming wspomniał. Po to aby kod wyglądał sensownie. Jeśli byś chciał to załatwić porównaniami musiałbyś porównać te elementy ze sobą:
1z2
1z3
1z4
1z5
1z6
1z6
1z7
1z8
1z9
1z10

2z3
2z4
2z5
2z6
2z7
2z8
2z9
2z10

3z4
3z5
3z6
3z7
3z8
3z9
3z10

4z5
4z6
4z7
4z8
4z9
4z10

5z6
5z7
5z8
5z9
5z10

6z7
6z8
6z9
6z10

7z8
7z9
7z10

8z9
8z10

9z10

Chyba nie chcesz mieć takiej ilości ifów??

Oczywiście można to zrobić za pomocą 2 pętli jedna w drugiej + FindComponent, ale to jest bez sensu.

0

Chodzi mi o poprawiony mój kod,chciałbym uniknąć tablicy.

0

Twojego kodu nie da się poprawić inaczej niż wyrzucając go i pisząc od nowa, tym razem z użyciem bufora pomocniczego; Przy czym FindComponent przyda się do uzupełnienia macierzy;

Ja bym proponował, aby referencje do wszystkich editów wrzucić do jednej tablicy, następnie wyniki konwersji wrzucić do drugiej tablicy; Na koniec poszukać duplikatów w tej drugiej.

0

Ale popatrz ile wtedy musisz mieć porównań. Dlatego napisałem czy byś tak samo robił jakbyś tych editów miał 100.

0

Czyli zrobić to w tablicy,posortować i później porónywać np.

if t[1]=t[2] then ...
0

Nie, używając pętli i algorytmu podobnego do sortowania bąbelkowego.

0

Nie rozumiem.

Co mam umieścić w tej pętli?

3

Masz przykładowy kod - celowo wykorzystałem gołe cyferki, abyś widział o co w tych pętlach chodzi:

type
  TNumbersArr = array [0 .. 9] of Integer;
const
  NUMBERS: TNumbersArr = (0, 1, 2, 3, 4, 1, 6, 7, 1, 9);
var
  intA, intB: Integer;
begin
  for intA := 0 to 8 do
    for intB := intA + 1 to 9 do
      if NUMBERS[intA] = NUMBERS[intB] then
        WriteLn('Dupliacate - ', intA, ' and ', intB);

  Write('done...');
  ReadLn();
end.

Wyjście:

Dupliacate - 1 and 5
Dupliacate - 1 and 8
Dupliacate - 5 and 8
done...

I teraz w zależności od potrzeb przerób powyższy kod.

0

Co oznacza ta linika ?

NUMBERS: TNumbersArr = (0, 1, 2, 3, 4, 1, 6, 7, 1, 9);
0

Deklaracja tablicy NUMBERS jako stałej; Służy jedynie dla przykładu, Ty w swoim kodzie użyj tablicy jako zmiennej i wypełnij ją liczbami, które pozyskasz podczas konwersji tekstu z komponentów.

0
Pogromca123 napisał(a):

Ale mi pomogłeś,może poczekam na odpowiedź kogoś bardziej ogarniętego.
wolfik ..

Mniemam, że o mnie chodzi :) więc spróbuję wyjść na ogarniętego i wpierw dopytam o rzeczy, których nie rozumiem.
Czy zależy Ci na porównywaniu tyko edit1 z edit2 potem edit3 z edit4 czy edit1 z edit2,3...n i tak dla wszystkich editów?
Drugie pytanie jaka wersja delphi bo jak masz delphi nowsze niż 2009 to możnaby pomyśleć o czymś "wykwintniejszym" jak np TDictionary :) Daj znać a spróbujemy coś pomóc choć wydaje mi się, że przykład od @furious programming powinien wystarczyc.

0

Ehh,nadal nie rozumiem jak to ma działać.Wersja Delphi 2007 ( nie mogę innej,projekt szkolny).


procedure TForm1.Button1Click(Sender: TObject);
begin
begin
memo1.clear;
end;
  For i:=1 to 22 do
    begin
      Pom[i]:=0 ;
    end;
  Randomize;
   For i:=1 to 6 do
    begin
      Repeat Buff:=Random(49); until (pom[Buff]=0) ;
      Tab[i]:=Buff;          
      pom[buff]:=1 ;
    end;
    begin
    for i:=1 to 6 do
     Memo1.Lines.Add(inttostr(tab[i] ));
     end;
end;

0

To jest już jedno porównanie do innej tablicy.

0

Ok odopowiedz jeszcze na moje drugie pytanie (a dokładnie pierwsze)

0

Chodzi mi tylko o porównanie kolejnych ntych editów do siebie i jeżeli któreś z nich są równe wyskakuje showmessage.

Czyli np.

if strtoint(edit1.text)=strtoint(edit2.text) then
showmessage('Te same liczby!')
else if strtoint(edit1.text)=strtoint(edit3.text) then..

Tylko bym musiał napisać tego kilkadziesiąt linijek i nie wiem po prostu jak to rozwiązać inaczej bo robienie tego dla 10 editów to będzie mnóstwo kodu...

0

Przypuszczam, że treścią zadania jest wylosowanie 6 liczb z 49 bez powtórzeń tak jak jest to w pewnej popularnej grze liczbowej.
Pom to prawdopodobnie u ciebie tablica 49 liczb z zerami jeśli wylosujesz jakąś to "skreślasz ją" oznaczając jedynką przy losowaniu wybierasz indeks danej liczby i sprawdzasz czy już została wylosowana. No może nie jest to najlepszy sposób na losowanie tych liczb, ale zawsze coś.
Pytania pomocnicze:
Dlaczego pierwsza pętla wypełnia tą tablicę pom tylko od 1 do 22 skoro liczb jest 49?
Random(49); losuje liczby z zakresu 0..48 pamiętaj o tym
Kryształowa kula podpowiada mi też, że te editki mają służyć do wprowadzenia przez użytkownika swoich typów - jeśli tak to dlaczego po prostu nie "skreślisz" tych liczb z tej tablicy pom, zliczysz ich ilość i jeśli nie będzie 6 skreślonych to albo się powtarzają albo nie wszystkie zostały wybrane.

2

To przecież @furious programming zapodał prawie gotowca tyle że zamiast stałej tablicy zrób dynamiczną lub listę np.:\

var
  EditList: TStringList;
  i, j: Integer;
begin
  Memo1.Clear;
  EditList:= TStringList.Create;
  try
    for i:=0 to Panel1.ControlCount -1 do //tylko edity ktore maja byc porownywane na panelu
      if Panel1.Controls[i] is TEdit then
        EditList.AddObject(Panel1.Controls[i].Name, TObject(StrToInt(TEdit(Panel1.Controls[i]).Text)));
    for i:= 0 to EditList.Count - 2 do
      for j:= i + 1 to EditList.Count - 1 do
        if Integer(EditList.Objects[i]) = Integer(EditList.Objects[j]) then
          Memo1.Lines.Add(Format('%0:s = %1:d i %2:s = %3:d', [EditList.Strings[i],
            Integer(EditList.Objects[i]), EditList.Strings[j], Integer(EditList.Objects[j])]));
  finally
    EditList.Free;
  end;
end;
1

Zaproponuję może swoje rozwiązanie, które powinno być dla pytacza zrozumiałe;

const
  INDEX_FIRST = 0;
  INDEX_LAST  = 9;

type
  TEditsArr  = array [INDEX_FIRST .. INDEX_LAST] of TEdit;
  TValuesArr = array [INDEX_FIRST .. INDEX_LAST] of Integer;

Deklaracja stałych i typów; Stałw przechowują indeksy dla macierzy, natomiast typy zawierają deklaracje macierzy do przechowywania editów oraz liczb, pozyskanych po konwersji tekstu z pól edycyjnych;

var
  eaEdits: TEditsArr;
  vaValues: TValuesArr;

Deklaracja zmiennych - eaEdits zawierać będzie referencje do pól edycyjnych, natomiast vaValues wyniki konwersji;

var
  intEditIdx: Integer;
begin
  for intEditIdx := INDEX_FIRST to INDEX_LAST do
  begin
    eaEdits[intEditIdx] := FindComponent(Format('Edit%d', [intEditIdx]));

    if not TryStrToInt(eaEdits[intEditIdx].Text, vaValues[intEditIdx]) then
    begin
      ShowMessage(Format('Edit%d nie zawiera liczby.', [intEditIdx]));
      eaEdits[intEditIdx].SetFocus();
      Exit();
    end;
  end;

Uzupełnienie macierzy wskazaniami na komponenty pól edycyjnych; Brak zabezpieczeń, więc komponenty o szukanych nazwach muszą istnieć na formularzu; W tej samej pętli następuje uzupełnienie macierzy vaValues - jeżeli konwersja nie powiedzie się, zostanie wyświetlony komunikat, następnie pole to zostanie aktywowane, a dalsze instrukcje w bloku kodu pominięte;

var
  intA, intB: Integer;
begin
  for intA := INDEX_FIRST to INDEX_LAST - 1 do
    for intB := intA + 1 to INDEX_LAST do
      if vaValues[intA] = vaValues[intB] then
      begin
        ShowMessage(Format('Edit%d zawiera powtórzoną liczbę.', [intB]));
        eaEdits[intB].SetFocus();
        Exit();
      end;

Wyszukiwanie duplikatów; Po znalezieniu powtórki zostaje wyświetlony komunikat, pole z powtórką aktywowane, a dalsze instrukcje i iteracje pętli pominięte; Kod bardzo prosty, niezbyt nowoczesny, jednak ma być zrozumiały dla początkującego;

PS: Cały kod należy wpakować do jednego bloku kodu, np. zdarzenia OnClick przycisku.

0

Nie jestem tak biegły z Delphi jak krzykliwyprogramer ale VCL chyba jest podobnie do C++ Buldera? Jeżeli umieścisz komponenty Edit na kontrolce która dziedziczy po TWinControl np. TForm lub TPanel to bez tworzenia tablicy można użyć property Controls[numer] oraz ControlsCount (Child). Po czym prostej petli:

bool duplikat = false;

for(int i = 0; i < Form1->ControlCount; i++)
    {
    for (int j = 0; j < Form1->ControlCount; j++)
        {
        // wyszły by dwie kontrolki o tych samych indeksach: idz dalej
        if (i==j)
            continue;
        // opcjonalne sprawdzenie czy kontrolka jest Edit'em
        if (dynamic_cast<TWinControl *>(Form1->Controls[i])->Name.Pos("Edit")==0 || dynamic_cast<TWinControl *>(Form1->Controls[j])->Name.Pos("Edit")==0)
            continue;
        // sprawdzenie zawartości
        if (dynamic_cast<TEdit *>(Form1->Controls[i])->Text == dynamic_cast<TEdit *>(Form1->Controls[j])->Text)
            {
            ShowMessage("Dupa jasia, w polach: " + dynamic_cast<TEdit *>(Form1->Controls[i])->Name + " oraz " + dynamic_cast<TEdit *>(Form1->Controls[j])->Name + " masz takie same wartości!");
            duplikat = true; break;
            }
        }
    if (duplikat==true) break;
    }

Podczas testowania użyłem Form1 bo nic na niej nie było poza Button1 i 10xEdit. Cudem Button nie wywołał problemu z rzutowaniem. Ale wypadało by zgrupować pola na Panel bo może być problem z dynamic_cast dla pozostałych komponentów w oknie(Access Violation). Nie da sie rzutować wszystkich na TControl a już tym bardziej po TEdit->Text.
Edity umieszczone samodzielnie na Panelu = zadziała bankowo(sprawdzałem).
Wystarczy to przekuć na pascala ;)

1

@stasinek - po co ten post?

Dwie pełne strony odpowiedzi, o Tobie się zachciało kolejne rozwiązanie i to nie dość że w innym języku, to jeszcze nieprawidłowe; Pytacz wyraźnie zaznaczył w tagu, że wątek dotyczy Delphi, nie C++, po drugie także wyraźnie zaznaczył, że porównywanie ma dotyczyć liczb, a nie tekstu; Twój kod zadziała nieprawidłowo i nie wykryje duplikatu, jeżeli w jedym polu wpiszę 5, a w drugim 05 lub 005 lub +5 (to te same liczby, a teksty różne);

Już nie wspominam o jakichś dziwnych continue zamiast prawidłowego indeksowania pętli, a także o przekazywaniu flagi duplikat z pętli do pętli i cudach z break, zamiast po prostu return false.

1

Ja tylko jeszcze dodam do tego co @furious programming napisał, że za dużo rzutowań w tym kodzie ma kolega @stasinek. Ja wiem, że czasem bez tego się nie obejdzie i sam stosuję rzutowania. Jednak takie coś stanowczo pogarsza czytelność kodu i początkujący może mieć z tym problem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1