Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Rechnen mit Mengen (https://www.delphipraxis.net/144517-rechnen-mit-mengen.html)

Highttower 9. Dez 2009 15:24


Rechnen mit Mengen
 
Hallo zusammen,

ich habe folgendes Problem:

Das kleine Rotkäpchen packt ihren Korb mit Lebensmitteln für ihre Großmutter zur Verfügung stehen ihr folgende Lebensmittel:

Delphi-Quellcode:
type
 TLebensmittel = (Moehren, Erbsen, Kartoffeln, Tomaten, Erdnuesse, Aepfel, Birnen, Banananen, Annanas, Sahnetorten, Fruchtkuchen, Lebkuchen, Spekulatius);

TKorb = set of TLebensmittel;
Soweit ist alles schön und gut :)

Jetzt möchte ich ihr aber sagen können, packe nur Obst, Gemüse oder nur Backwaren ein.

Dazu bin ich bisher so vorgegangen:

Delphi-Quellcode:
type
TLebensmittelgruppen = (Obst, Gemuese, Backwaren)

var
FKorb : TKorb;

impelmentation

procedure packeKorbEin(AGruppe : TLebensmittelgruppen );
begin
    case AGruppe of
        Obst: begin
            FKorb := FKorb + Aepfel, Birnen, Banananen, Annanas;
        end;
        Gemuese: begin
            FKorb := FKorb + Moehren, Erbsen, Kartoffeln, Tomaten;
        end;
        Backwaren: begin
            FKorb := FKorb + Sahnetorten, Fruchtkuchen, Lebkuchen, Spekulatius;
        end;
    end;
end;
Da Rotkäpchen aber sehr vergässlich ist, guckt sie noch einmal nach ob noch alles da ist:

Delphi-Quellcode:
procedure guckeInKorb;
var neSache : TLebensmittel;
begin
    for neSache in FKorb do begin
        case neSache of
            Aepfel, Birnen: ShowMessage('Heimische Früchte hab ich!');
            Banananen, Annanas: ShowMessage('Exotische Früchte hab ich!');
            Moehren, Erbsen, Kartoffeln: ShowMessage('Gemüse hab ich!');
            Tomaten: ShowMessage('Tomaten aus dem eigenen Garten hab ich!');
            Sahnetorten, Fruchtkuchen, Lebkuchen, Spekulatius: ShowMessage('Sachen die dick machen hab ich!');
            else: ShowMessage('Den andern Kram wie Erdnüsse und so hab ich auch!')
    end;
end;
Wie ihr seht reicht ihr oft eine Sache von einer ganzen Gruppe von Sachen. Daher will sie danach nicht mehr danach suchen müssen, Äpfel und Birnen sehen ja auch ähnlich aus. Darum packt sie das Obst einfach aus dem Korb heraus ... und genau das will nicht klappen:

Delphi-Quellcode:
type
THeimischesObst = (Aepfel, Birnen);
TExotischesObst = (Bananen, Annanas);
TGemuese = (Moehren, Erbsen, Kartoffeln);
// usw.

implementation

procedure guckeInKorb;
var neSache : TLebensmittel;
begin
    for neSache in FKorb do begin
        case neSache of
            THeimischesObst : begin
                FKorb = FKorb - THeimischesObst;
                ShowMessage('Heimische Früchte hab ich!');
            end;
            TExotischesObst :begin
                FKorb = FKorb - TExotischesObst ;
                ShowMessage('Exotische Früchte hab ich!');
            end;
            TGemuese :begin
                FKorb = FKorb - TGemuese ;
                ShowMessage('Gemuese hab ich!');
            end;
            Tomaten: ShowMessage('Tomaten aus dem eigenen Garten hab ich!');
            TGebaeck: begin
                FKorb = FKorb - TGebaeck;
                ShowMessage('Gebäck hab ich!');
            end;
            else: ShowMessage('Den andern Kram wie Erdnüsse und so hab ich auch!')
    end;
end;
Das Problem daran ist er versteht nicht das das Teilmengen sind. Kann mir jemand erklären wie das in Delphi geht? Hier in dem Beispiel habe ich jetzt die Typen genommen, es bringt auch nix wenn ich davon "Objekte" anlege.

Das hier habe ich mir angeguckt bringt mich aber nicht sonderlich weiter.

Vielen Dank,

Tobias

shmia 9. Dez 2009 15:56

Re: Rechnen mit Mengen
 
Du brauchst keine Typdeklaration, sondern Konstanten:
Delphi-Quellcode:
type
TLebensmittel = (Moehren, Erbsen, Kartoffeln, Tomaten, Erdnuesse, Aepfel, Birnen, Banananen, Annanas, Sahnetorten, Fruchtkuchen, Lebkuchen, Spekulatius);

TKorb = set of TLebensmittel;

const
   Obst:TKorb = [Aepfel, Birnen, Banananen, Annanas];
   HeimischesObst:TKorb = [Aepfel, Birnen];
   ExotischesObst:TKorb = [Bananen, Annanas];
   KotztsichGut:TKorb = [Sahnetorten, Erbsen];

Highttower 9. Dez 2009 16:17

Re: Rechnen mit Mengen
 
Hallo,
vielen Dank für den Versuch aber der Compiler meckert immer noch es sei ein Konstantenausdruck erwartet .... Dabei habe ich doch jetzt Konstanten:


type
THeimischesObst = (Aepfel, Birnen);
TExotischesObst = (Bananen, Annanas);
TGemuese = (Moehren, Erbsen, Kartoffeln);
// usw.

implementation
Delphi-Quellcode:
procedure guckeInKorb;
var neSache : TLebensmittel;
const
    HeimischesObst:TKorb = [Aepfel, Birnen];
    ExotischesObst:TKorb = [Bananen, Annanas];
    Gemuese : TKorb = [Moehren, Erbsen, Kartoffeln];
begin
    for neSache in FKorb do begin
        case neSache of
            HeimischesObst : begin
                FKorb = FKorb - THeimischesObst;
                ShowMessage('Heimische Früchte hab ich!');
            end;
            ExotischesObst :begin
                FKorb = FKorb - TExotischesObst ;
                ShowMessage('Exotische Früchte hab ich!');
            end;
            Gemuese :begin
                FKorb = FKorb - TGemuese ;
                ShowMessage('Gemuese hab ich!');
            end;
            Tomaten: ShowMessage('Tomaten aus dem eigenen Garten hab ich!');
            TGebaeck: begin
                FKorb = FKorb - TGebaeck;
                ShowMessage('Gebäck hab ich!');
            end;
            else: ShowMessage('Den andern Kram wie Erdnüsse und so hab ich auch!')
    end;
end;
Auch die Typen zu ändern auf Lebensmittel oder Set of Lebensmittel bringt nix. Allerdings Rechnen kann ich damit jetzt :). Hat noch jemand eine Idee?

Delphi-Quellcode:
    FKorb := FKorb - Gemuese; // funktioniert =)
Vielen Dank,

Tobias

himitsu 9. Dez 2009 16:35

Re: Rechnen mit Mengen
 
Zitat:

Zitat von Highttower
type
THeimischesObst = (Aepfel, Birnen);
TExotischesObst = (Bananen, Annanas);
TGemuese = (Moehren, Erbsen, Kartoffeln);
// usw.

Aepfel ist vom Typ THeimischesObst und paßt nicht in den Typ TLebensmittel/TKorb.

Schau mal, wie es shmia genau gemacht hat.

Highttower 9. Dez 2009 16:42

Re: Rechnen mit Mengen
 
Oh, Verzeihung da hab ich zu viel kopiert:


So sieht es jetzt bei mir aus:

Delphi-Quellcode:
procedure guckeInKorb;
var neSache : TLebensmittel;
const
    HeimischesObst:TKorb = [Aepfel, Birnen];
    ExotischesObst:TKorb = [Bananen, Annanas];
    Gemuese : TKorb = [Moehren, Erbsen, Kartoffeln];
    Gebaeck : TKorb = [Kuchen (* usw.*)]
begin
    for neSache in FKorb do begin
        case neSache of
            HeimischesObst : begin
                FKorb = FKorb - HeimischesObst;
                ShowMessage('Heimische Früchte hab ich!');
            end;
            ExotischesObst :begin
                FKorb = FKorb - ExotischesObst ;
                ShowMessage('Exotische Früchte hab ich!');
            end;
            Gemuese :begin
                FKorb = FKorb - Gemuese ;
                ShowMessage('Gemuese hab ich!');
            end;
            Tomaten: ShowMessage('Tomaten aus dem eigenen Garten hab ich!');
            Gebaeck: begin
                FKorb = FKorb - Gebaeck;
                ShowMessage('Gebäck hab ich!');
            end;
            else: ShowMessage('Den andern Kram wie Erdnüsse und so hab ich auch!')
    end;
end;
Die Typendeklaration habe ich schon lange von Bord geschmissen :), hätte aber eh wenig auswirkungen da ich ja auf HeimischesObst und nicht auf THeimischesObst im Case prüfe ;). Danke trozdem für den Hinweis, außer bei dem rechenkram...

himitsu 9. Dez 2009 16:48

Re: Rechnen mit Mengen
 
das sollte gehn
Delphi-Quellcode:
for neSache in FKorb do begin
  if neSache in HeimischesObst them begin
    FKorb = FKorb - HeimischesObst;
    ShowMessage('Heimische Früchte hab ich!');
  end
  else if neSache in ExotischesObst then begin
    FKorb = FKorb - ExotischesObst;
    ShowMessage('Exotische Früchte hab ich!');
  end
  ...
PS: typisierte Konstanten werden wie Variablen angesehn/behandelt, welche aber nicht verändert werden dürfen.
Delphi-Quellcode:
const HeimischesObst[b]: TKorb[/b] = ...
probiere es mal so,
Delphi-Quellcode:
const
  HeimischesObst = [Aepfel, Birnen];
  ExotischesObst = [Bananen, Annanas];
  Gemuese = [Moehren, Erbsen, Kartoffeln];
  Gebaeck = [Kuchen (* usw.*)]
aber es kann auch sein, daß CASE solche Konstanten garnicht versteht.

shmia 9. Dez 2009 16:54

Re: Rechnen mit Mengen
 
Das sieht immer noch etwas seltsam aus in deinem Code.
So müsste es passen:
Delphi-Quellcode:
var neSache : TLebensmittel;
const
    HeimischesObst:TKorb = [Aepfel, Birnen];
    ExotischesObst:TKorb = [Bananen, Annanas];
    Gemuese : TKorb = [Moehren, Erbsen, Kartoffeln];
    Gebaeck : TKorb = [Kuchen (* usw.*)]
begin
   ...
   if neSache in HeimischesObst then
      ShowMessage('Heimische Früchte hab ich!');

   if neSache in ExotischesObst then
      ShowMessage('Exotische Früchte hab ich!');

   // man kann auch alles auf einen Rutsch prüfen
   // und die Schnittmenge bilden
   if (korb * HeimischesObst) <> [] then
      ShowMessage('Heimische Früchte sind im Korb');

Highttower 9. Dez 2009 17:06

Re: Rechnen mit Mengen
 
hmmm hab ich alles schon versucht....

Delphi-Quellcode:

for neSache in FKorb do begin
  if neSache in HeimischesObst them begin
    FKorb = FKorb - HeimischesObst;
    ShowMessage('Heimische Früchte hab ich!');
  end
  else if neSache in ExotischesObst then begin
    FKorb = FKorb - ExotischesObst;
    ShowMessage('Exotische Früchte hab ich!');
  end
  ...
Ist equivalent und um einiges langsamer zu:

Delphi-Quellcode:
if HeimischeObst in FKorb then begin
    FKorb = FKorb - HeimischesObst;
    ShowMessage('Heimische Früchte hab ich!');
  end
  else if ExotischesObst in FKorb then begin
    FKorb = FKorb - ExotischesObst;
    ShowMessage('Exotische Früchte hab ich!');
  end
  ...
Wenn man die unter Lösung nimmt kommt wieder das Problem das die Äpfel, dann zu heimisch sind aber keiner Lebensmittel mehr -.-. Weil er dann annimmt das wären verschiedene Daten.

Mfg

Tobi

Oh rote Box ...

Hmm ja dann werde ich wohl doch alles mit If abfackeln müssen, das war eigendlich das was ich nicht wollte, weil meine Orginal Source ungefair so viele Typen hat wie ein Großmarkt. -.-

Wenn noch jemand eine Idee hat wie man das Case bei biegt wäre ich sehr verbunden.


PS: Mir ist durch ausbewusst das ein set nur 255 versch. Datentypen haben kann .... aber darum ja die Gruppen, um Sets mit einander zu verbinden.

EDIT:
Hallo zusammen,

ich hab meinen Denkfehler gefunden:

Eine Menge ist kein Ordinalwert und darum nicht in case of verwendbar.

@Admin / Mod:
Wie kennzeichne ich jetzt als beantwortet, der Harken als offene Frage makieren ist nicht da. Ich kann ihn also nicht rausnehmen-.-


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz