Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (WinAPI, Konsole) » Aufgabe: münzautomat

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
25.10.2004, 13:00 Uhr
johnnyblaze1978



steh vor einem Problem, an dem ich mir das ganze we die zähne ausgebissen hab und irgendwie nicht weiterkomme........
ich bin c++ greenhorn und soll folgendes programm erstellen....wäre super, wenn mir da jemand weiterhelfen könnte......
Es soll ein essensautomat aufgestellt werden, bei dem nur mit münzen gezahlt werden kann. es sollen dem käufer mittels computer alle möglichkeiten aufgezeigt werden.....es gibt 1,2,5er münzen.
beim kaufpreis von 3euro soll es folgendermaßen aussehen:

1 1 1
1 2
2 1

der maximale kaufpreis beträgt 20 euro??????

kann mir da jemand weiterhelfen????????????wäre super!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.10.2004, 13:08 Uhr
Goos



Dann schreib doch bitte erstmal, welche Loesungsansaetze du dir bisher so erdacht hast.
Man kann die dann ja verbesser und weiter ausarbeiten.

Goos
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
25.10.2004, 13:16 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


wenn der lösungsraum so eingeschränkt ist kann man ja glatt alle Lösungen aufschreiben in ein lookuptable ballern und dann entsprechend ausgeben...
dann hat man auch die performantes Lösung von allen
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
25.10.2004, 14:18 Uhr
~Spacelord
Gast


Ohne weiter darüber nachzudenken behaupte ich mal dass sich das Problem rekursiv recht elegant lösen lassen müsste....

MfG Spacelord
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
25.10.2004, 14:20 Uhr
(un)wissender
Niveauwart


Allerdings, ist sogar ein Paradebeispiel für sowas. Bei mehrMünzen und einer größeren Summe immer gut für einen Stackoverflow.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
25.10.2004, 16:38 Uhr
(un)wissender
Niveauwart


Ach ja, alle Permutationen?
Also ist bei dir 112 = 211 = 121?
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
25.10.2004, 16:54 Uhr
johnnyblaze1978




Zitat von (un)wissender:
Ach ja, alle Permutationen?
Also ist bei dir 112 = 211 = 121?

ja genau, hab keine ahnung, wie ich sowas programmieren kann, zumal dann noch die 5 dazukommt....???
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
25.10.2004, 17:08 Uhr
0xdeadbeef
Gott
(Operator)


Ich hab grad mal folgendes zusammengeschustert:

C++:
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>

std::vector<std::set<std::string> > muenzverteilungen(21);

void muenz_rek(std::string const &s, unsigned x, unsigned rest) {
  if(rest == 0) {
    std::string t = s;
    std::sort(t.rbegin(), t.rend());
    muenzverteilungen[x].insert(t);
  } else {
    if(rest >= 5)
      muenz_rek(s + "5", x, rest - 5);
    if(rest >= 2)
      muenz_rek(s + "2", x, rest - 2);
    if(rest >= 1)
      muenz_rek(s + "1", x, rest - 1);
  }
}

int main() {
  for(int i = 1; i <= 20; ++i) {
    muenz_rek("", i, i);
    std::cout << i << std::endl << "---" << std::endl;
    for(std::set<std::string>::reverse_iterator j = muenzverteilungen[i].rbegin();
        j != muenzverteilungen[i].rend();
        ++j)
      std::cout << *j << std::endl;
    std::cout << "---" << std::endl;
  }
}


Das entfernt dann auch gleich doppelte Treffer.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
25.10.2004, 18:45 Uhr
johnnyblaze1978



vielen dank für diesen beitrag..........aber leider versteh ich nur bahnhof..............geht es denn nicht einfacher ? gerade für mich als anfänger. hab mit klassen und so noch nix am hut.....wäre super, wenn s da alternativen gäbe.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
25.10.2004, 19:47 Uhr
0xdeadbeef
Gott
(Operator)


Einfacher wärs noch so, denke ich. Ist jedenfalls schneller. Der Gedanke ist, erst die Möglichkeiten für 1 Münze zu berechnen, dann darauf die für 2, dann aus denen für 1 und 2 Münzen die für 3 usw, und dabei doppelte entfernen.

std::set ist ein Container, der das selbe Element nur einmal vorhält, wenn ich also "211" im set drinhabe und "211" einfügen will, ist nachher trotzdem nur ein mal "211" drin, wenn ich also die Strings vorher sortiere (mit std::sort), schmeiße ich auf die Art doppelte Einträge raus.

C++:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <set>
#include <sstream>
#include <string>
#include <vector>

int main() {
  // Ein Vektor (quasi gekapseltes Array) von sets (Mengen) von Strings, 21 Einträge
  std::vector<std::set<std::string> > muenzen(21);

  muenzen[0].insert(""); // Iterationsanfang, keine Möglichkeiten ohne Münzen

  // std::vector<std::set<std::string> >::size_type ist ein vorzeichenloser integraler Typ,
  // halt zur Indizierung des vectors.
  for(std::vector<std::set<std::string> >::size_type i = 1; i <= 20; ++i)
    // j nimmt die Werte 5, 2, und 1 an - war die kürzeste Art, das zu schreiben.
    for(int j = 5; j > 0; j /= 2)
      // Hier die eigentliche Konstruktion. Die Verteilungsmöglichkeiten für 10 Münzen sind
      // eine 5 und die Aufteilungsmöglichkeiten für 5 Münzen, eine 2 und die Aufteilungsmöglichkeiten
      // für 8 Münzen und eine 1 und die Aufteilungsmöglichkeiten für 9 Münzen zusammengefasst.
      // Also:
      if(i >= j) {
        // j in einen String umwandeln
        std::stringstream sout;
        sout << j;

        for(std::set<std::string>::iterator k = muenzen[i - j].begin();
            k != muenzen[i - j].end();
            ++k) {
          // den String mit der gerade betrachteten Möglichkeit zusammenketten
          std::string s = sout.str() + *k;
          // Sortieren für Übersicht und Aussonderung doppelter Treffer
          std::sort(s.rbegin(), s.rend());
          // Und das Ergebnis speichern. set sortiert doppelte Einträge automatisch aus.
          muenzen[i].insert(s);
        }
      }

  // Ausgabe aller Möglichkeiten
  for(std::vector<std::set<std::string> >::size_type i = 1; i <= 20; ++i) {
    std::cout << "---" << std::endl
              << i     << std::endl
              << "---" << std::endl;
    std::copy(muenzen[i].rbegin(),
              muenzen[i].rend(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
  }
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (WinAPI, Konsole) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: