JavaRush /Java-Blog /Random-DE /Rätsel mit Klammern (Stufe 3, Vorlesung 4)
Anatoliy
Level 17

Rätsel mit Klammern (Stufe 3, Vorlesung 4)

Veröffentlicht in der Gruppe Random-DE
Ich glaube, dass es eine solche Aufgabe gibt, die bei vielen JavaRush-Kadetten unterschiedliche Emotionen hervorgerufen hat. Im September, als ich mit dem Kurs begann, war die Aufgabe wie folgt formuliert: Platziere im Ausdruck 1+2*3+4*5+6*7+8*9+10 zwei Klammerpaare so, dass der Wert der Ausdruck wird gleich 537
Puzzle mit Klammern (3. Level, 4. Lektion) - 1
Als ich nun zur Lösung zurückkehrte, stellte ich fest, dass der Wortlaut geändert wurde; es ist notwendig, zwei Klammerpaare in den Ausdruck 2*3+4*5+6*7 einzufügen, damit der Wert gleich 382 wird Der neue Zustand ist natürlich einfacher als der vorherige, weil die Zahl der möglichen Optionen hat sich um etwa eine Größenordnung verringert. Aber die restlichen 85 reichen völlig aus, um ein oder zwei Stunden mit der manuellen Suche zu verbringen. Offensichtlich hat die Aufgabe nicht direkt mit der Java-Programmierung zu tun. Deshalb habe ich es nicht gelöst. Für solche Probleme gibt es keine analytischen Lösungen, die auf Überlegungen oder den Eigenschaften von Zahlen basieren, sondern nur rohe Gewalt, nämlich eine stumpfe Suche nach allen möglichen Optionen. Andererseits ist es nicht weniger offensichtlich, dass Probleme dieser Art mit Hilfe der Programmierung gelöst werden. Deshalb bin ich zurückgekommen. Ich habe mich gerade erst an die IDE gewöhnt, und die Probleme des Kurses in Level 8 haben mich umgehauen, und es hat mir nichts ausgemacht, ein oder zwei Abende damit zu verbringen, sie zu lösen. Im Folgenden erfahren Sie, wie Sie dieses Problem mit Java lösen können. Als Grundlage für das Beispiel habe ich den alten Zustand verwendet. Zunächst benötigen wir eine Möglichkeit, den Wert eines als String geschriebenen Ausdrucks zu berechnen. Eine solche Methode konnten wir in den Standard-Java-Bibliotheken nicht finden. Ich habe Folgendes gegoogelt: http://www.cyberforum.ru/java-j2se/thread283139.html ist für unsere Zwecke durchaus geeignet. Der Algorithmus basiert auf der umgekehrten polnischen Notation und funktioniert für gültige Zeichenfolgen, die vier arithmetische Operationen und Klammern enthalten. Erstellen Sie ein neues Projekt mit der PPN-Klasse darin, kopieren Sie den Code aus dem Link und fügen Sie ihn in eine Datei ein. Das Problem kann in der main()-Methode der PPN-Klasse gelöst werden. Aber es ist nicht notwendig. Die Java-Ideologie basiert auf der Aufteilung eines Problems in kleine Teilaufgaben, die jeweils in einer eigenen Klasse und Methode implementiert werden. Ein guter Ansatz wäre, das Problem in einer anderen Klasse zu lösen, die in einer separaten Datei gespeichert wird. Erstellen Sie daher eine weitere Klasse, in der Sie den Algorithmus zum Aufzählen von Klammern schreiben. Um den Wert einer Zeichenfolge zu berechnen, müssen Sie die Methode eval() der PPN-Klasse aufrufen: Zum Beispiel so
System.out.println(PPN.eval(2*3+4));
oder so
int result = PPN.eval(s2);
Schauen wir uns die Zeile 1+2*3+4*5+6*7+8*9+10 genau an und fragen uns, auf wie viele Arten wir eine öffnende Klammer setzen können. Es kann auf zehn Arten platziert werden. Wenn Sie die Zeichen einer Zeichenfolge beginnend bei Null nummerieren, kann die öffnende Klammer an den Positionen {0,2,4,6,8,10,12,14,16,18} platziert werden. Wenn Sie beispielsweise eine Klammer an der sechsten Position platzieren, müssen Sie alle Zeichen von null bis einschließlich fünf verwenden, dann eine Klammer einfügen und dann alle Zeichen von der sechsten bis zum Ende der Zeile verwenden:
Puzzle mit Klammern (3. Level, 4. Lektion) - 2
Ebenso kann die schließende Klammer an den Positionen {1,3,5,7,9,11,13,15,17,20} platziert werden. Die letzten beiden Zahlen verderben die ganze Himbeere, alle anderen Positionen weichen um zwei voneinander ab, 17 und 20 um drei. Daher wird es nicht möglich sein, einfach eine Variable zu deklarieren, die die Positionsnummer der schließenden Klammer enthält, und ihren Wert bei jedem nächsten Schritt um zwei zu erhöhen. Wir werden Positionswerte in Arrays speichern:
int[] left = {0,2,4,6,8,10,12,14,16,18};
int[] right = {1,3,5,7,9,11,13,15,17,20};
Und wir werden die Indexvariable bei jeder Iteration der Schleife, die für die Aufzählung von Optionen verantwortlich ist, um eins erhöhen. Insgesamt werden zwei öffnende und zwei schließende Klammern bzw. vier Indexvariablen benötigt:
int indLeft1, indLeft2, indRight1, indRight2;
Klammern in einem Ausdruck können auf zwei Arten gesetzt werden:
(  )  (  )
(  (  )   )
Für jede Methode müssen Sie Ihren eigenen Algorithmus schreiben; betrachten Sie den Algorithmus für die erste Methode zum Anordnen von Klammern. Die eigentliche Aufzählung der Optionen wird durch verschachtelte for-Schleifen dargestellt:
for (int indLeft1=0;indLeft1<10;indLeft1++)
   for(int indRight1=indLeft1+1;indRight1<10;indRight1++)
      for (int indLeft2=indRight1+1;indLeft2<10;indLeft2++)
         for (int indRight2=indLeft2+1;indRight2<10;indRight2++)
Zu Beginn des Programms initialisieren wir die String-Variable mit dem Original-String ohne Klammern:
String s = "1+2*3+4*5+6*7+8*9+10";
Im Körper der inneren Schleife bilden wir eine Linie mit Klammern:
String s2 = s.substring(0, left[indLeft1]) + "(" +
		 s.substring(left[indLeft1], right[indRight1]) + ")" +
		 s.substring(right[indRight1],left[indLeft2]) + "(" +
		 s.substring(left[indLeft2], right[indRight2]) + ")" +
		 s.substring(right[indRight2], s.length());
Beachten Sie die Besonderheit der Methode substring() der Klasse String. Es wird eine Teilzeichenfolge ausgewählt, deren Nummer des ersten Zeichens gleich dem ersten Parameter ist und deren Nummer des letzten gleich dem zweiten Parameter minus eins ist . siehe https://docs.oracle.com/javase/10/docs/api/java/lang/String.html#substring(int,int) , es werden sogar Beispiele gegeben, um Missverständnisse zu reduzieren. Nachdem wir eine Zeichenfolge mit Klammern gebildet haben, berechnen wir den Wert und vergleichen ihn mit dem erforderlichen Wert:
int result = PPN.eval(s2);
if (result == 537)
          System.out.println(s2);
Der Block zur verschachtelten Anordnung von Klammern wird auf ähnliche Weise geschrieben. Das Einzige, worauf ich aufmerksam machen möchte, ist, dass bei der Verschachtelung der Klammern beispielsweise die öffnende oder schließende Klammer an der gleichen Position stehen kann
1+((2*3+4*5+6)*7+8*9+10)
oder
(1+2*(3+4*5+6*7+8))*9+10
Eigentlich ist das alles. Nach dem Start erzeugt ein korrekt geschriebenes Programm eine einzige Antwort: 1+2*(3+4*(5+6*7)+8*9)+10
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION