BPS #21: Strings attached - Auswertung

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Xeres

Moderator

Betreff: BPS #21: Strings attached - Auswertung

BeitragSo, Jun 24, 2012 11:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Legt Schere und Kleber nieder und zeigt, was ihr mit den Strings angestellt habt!

Das war die Aufgabe

Postet hier eure Ergebnisse, Codes, Gedanken. Lernt von den anderen, seht euch deren Quelltext an und versucht euren eigenen zu verbessern.

Diskussion
Postet zu euren Codes stets eine kurze Erklärung mit euren Gedanken in denen ihr simpel gesagt die Frage "Wieso habe ich XY auf diese Art gelöst?" beantwortet. Beiträge, die nur den Code enthalten werden wir aus dem Thread entfernen.

Nächste Aufgabe
In einer Woche wird die Musterlösung nach editiert und in 2 die nächste Aufgabe eingestellt.

Viel Spaß & viel Erfolg!

Musterlösung:
BlitzMax: [AUSKLAPPEN]
SuperStrict

Local Source:String = "Wozu sollte man das brauchen?"

Print("Original: " + Source)
Print("Rückwärts: " + Reverse(Source))
Print("Leerzeichen: " + Count(Source, " "))
Print("Fragezeichen: " + Count(Source, "?"))
Print("Ist 'Dormitory' ein Anagramm von 'Dirty Room' ?: ")
Print(WahrFalsch(IsAnagramm("Dormitory'", "Dirty Room")))
Print("Ist 'Reittier' ein Palindrom?: ")
Print(WahrFalsch(IsPalindrom("reittier")))
End

Function Reverse:String(txt:String)
Local backwards:String, i:Int

For i = txt.Length - 1 To 0 Step - 1
backwards = backwards + Chr(txt[i])
Next

Return backwards
End Function

Function Count:Int(txt:String, symbol:String)
Local p:Int = txt.Find(symbol), n:Int
If p = -1 Then Return 0

Repeat
p = txt.Find(symbol, p + 1)
n:+1
Until p = -1

Return n
End Function

Function IsAnagramm:Int(txt1:String, txt2:String)
txt1 = Lower(txt1)
txt2 = Lower(txt2)

Local char:Int[26], c:Int, i:Int

For i = 1 To Len(txt1)
c = Asc(Mid(txt1, i, 1))

' a z
If c >= 97 And c <= 122 Then
char[c - 97] = char[c - 97] + 1
EndIf
Next

For i = 1 To Len(txt2)
c = Asc(Mid(txt2, i, 1))

If c >= 97 And c <= 122 Then
char[c - 97] = char[c - 97] - 1
EndIf
Next

For i = 0 To 25
If char[i] <> 0 Then
Return False
EndIf
Next

Return True
End Function

Function IsPalindrom:Int(txt:String)
If txt = Reverse(txt) Then
Return True
Else
Return False
EndIf
End Function

Function WahrFalsch:String(value:Int)
If value Then
Return "Wahr"
Else
Return "Falsch"
EndIf
End Function
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
  • Zuletzt bearbeitet von Xeres am So, Jul 08, 2012 13:56, insgesamt 2-mal bearbeitet
 

CO2

ehemals "SirMO"

BeitragSo, Jun 24, 2012 15:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier mal meine Lösung (Der Code sollte sich von alleine klären, wenn nicht: Fragen):
BlitzMax: [AUSKLAPPEN]
Rem
Aufgabe:
Schreibe folgende Funktionen:
Die erste soll einen String umdrehen, sodass alle Zeichen in der umgekehrten Reihenfolge, von hinten nach vorn, stehen.
Die zweite soll die Vorkommnisse eines bestimmten Buchstaben in einem String zählen.
Die dritte und vierte Funktion, sollten ein Anagramm und ein Palyndrom erkennen können.
Euer Code sollte die Funktionen natürlich kurz Vorführen.
End Rem


Rem
Autor: Marius Otto
Datum: 20.06.2012
Version: 1.0
End Rem


' ###################################### Eine Hilfsfunktion (Benötigt für 3. und 4. Funktion #######################################
Function SchreibeAllesGross:String(Text:String) 'Hilfsfunktion, die den String komplett groß schreibt
Local Laenge:Int = Len(Text) 'Länge herausfinden
Local Ergebnis:String = "" 'Hier wird das Ergebnis gespeichert
For Local momentanerBuchstabe:Int = 0 To Laenge 'Solange nicht das Ende des Strings erreicht ist...
If(Asc(Mid(Text, momentanerBuchstabe, 1)) >= 97 And Asc(Mid(Text, momentanerBuchstabe, 1)) <= 122) 'Kontrolliere, ob das momentane Zeichen ein Kleinbuchstabe ist (Siehe ASCII-Tabelle)
Ergebnis = Ergebnis + Chr(Asc(Mid(Text, momentanerBuchstabe, 1)) - 32) 'Wenn Ja, In Großbuchstaben umwandeln (Siehe ASCII-Tabelle)
Else
Ergebnis = Ergebnis + (Mid(Text, momentanerBuchstabe, 1)) 'Sonst einfach den Buchstaben übernehmen (Da er entweder Ein Zeichen, oder schon ein Großbuchstabe ist)
EndIf
Next
Return Ergebnis 'Zum Schluss String zurückgeben
End Function

' ########################################### Dies ist die 1. Funktion (String umdrehen) ###########################################
Function TextUmdrehen:String(Text:String)
Local Laenge:Int = Len(Text) 'Finde die String-länge heraus
Local Ergebnis:String = "" 'In diesen String wird das gespeichert, was zurückgegeben werden soll.
For Local momentanePosition:Int = Laenge To 0 Step -1 'Solange momentanePosition nicht 0 (Also der Anfang vom String nicht erreicht)...
Ergebnis = Ergebnis + (Mid(Text, momentanePosition, 1)) '...Finde den momentan zu betrachtenden Buchstaben heraus und hänge ihn an returnstring
Next
Return Ergebnis 'Zum Schluss noch modifizierten String zurückgeben
End Function

' ############################ Dies ist die 2. Funktion (Vorkommnisse eines Buchstaben in einem Text). ############################
Function AnzahlEinesBuchstabenImText:Int(Text:String, Buchstabe:String)
Local Laenge:Int = Len(Text) 'Finde Länge des Textes heraus
Local Summe:Int = 0 'Hier wird das Ergebnis gespeichert
For Local momentanerBuchstabe:Int = 0 To Laenge 'Solange momentanerBuchstabe nicht LängeDesStrings (Also Ende des Strings erreicht)...
If(Mid(Text, momentanerBuchstabe, 1) = Buchstabe) '...Wenn der momentane Buchstabe gleich dem zu suchenden Buchstaben ist,...
Summe = Summe + 1 '...Erbnis + 1
EndIf
Next
Return Summe 'Zum Schluss Ergebnis zurückgeben
End Function

' ####################################### Dies ist die 3. Funktion (Text auf Anagramm testen) ######################################
Function Anagramm:Int(Text:String, TestenAuf:String)
For Local Zaehler:Int = 0 To 25 'Alle Buchstaben des Alphabets durchgehen
If(AnzahlEinesBuchstabenImText(SchreibeAllesGross(Text), Chr((Zaehler + 65))) <> AnzahlEinesBuchstabenImText(SchreibeAllesGross(TestenAuf), Chr((Zaehler + 65)))) 'Sollte Ein Buchstabe in dem einen Text nicht sooft vorkommen wie in dem anderen, so ist es kein anagramm, also...
Return 0 '0 (False) Zurückgeben
EndIf
Next
Return 1 'Sollte die Schleife komplett durchgelaufen sein, 1 (True) Zurückgeben
End Function

' ###################################### Dies ist die 4. Funktion (Text auf Palindrom testen) ######################################
Function Palindrom:Int(Text:String)
If(SchreibeAllesGross(Text) = SchreibeAllesGross(TextUmdrehen(Text))) 'Schreibe alles groß, kontrolliere dann, ob der normale Text dem umgedrehten entspricht,...
Return 1 '...Wenn ja, 1 (True) zurückgeben
Else
Return 0 '...Sonst 0 (False) zurückgeben
EndIf
End Function

' ############################################################ TestCode ############################################################
Local TestText:String = "Wozu sollte man das brauchen?"
Print("Original: " + TestText + "")
Print("Rückwärts: " + TextUmdrehen(TestText))
Print("Leerzeichen: " + AnzahlEinesBuchstabenImText(TestText, " "))
Print("Fragezeichen: " + AnzahlEinesBuchstabenImText(TestText, "?"))
Print("Ist 'Dormitory' ein Anagramm von 'Dirty Room'?")
If(Anagramm("Dirty Room", "Dormitory") = 1)
Print("Wahr")
Else
Print("Falsch")
EndIf
Print("Ist 'Reittier' ein Palindrom?")
If(Palindrom("Reittier") = 1)
Print("Wahr")
Else
Print("Falsch")
EndIf

End
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Xeres

Moderator

BeitragSo, Jun 24, 2012 16:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Einzig deine SchreibeAllesGross Funktion könntest du durch die eingebaute Upper Funktion/ ToUpper Methode ersetzen, die auch Umlaute respektieren:
BlitzMax: [AUSKLAPPEN]
Print("klein äöüß".ToUpper())
Print(SchreibeAllesGross("klein äöüß"))

Da Strings Objekte sind, gibt es feine, eingebaute Methoden, für die man nicht zwangsläufig die Retro-Funktionen gebrauchen muss:
BlitzMax: [AUSKLAPPEN]
Print("ABC".length)

Ich schätze aber nicht, dass es einen überragenden Unterschied macht - es funktioniert ja Problemlos.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

FireballFlame

BeitragSo, Jun 24, 2012 23:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich mach auch mal mit Razz

Mid etc. finde ich hässlich. Daher hier meine Lösung mit Slices!


BlitzMax: [AUSKLAPPEN]

SuperStrict

Framework BRL.StandardIO





Local a:String = "Wozu sollte man das brauchen?"
Local b1:String = "Dormitory"
Local b2:String = "Dirty Room"
Local c:String = "Reittier"


Print "Original:~t" + a
Print "Rückwärts:~t" + StringTools.Reverse(a)
Print "Leerzeichen:~t" + StringTools.CountOccurences(a, " ")
Print "Fragezeichen:~t" + StringTools.CountOccurences(a, "?")

Print "Ist '" + b1 + "' ein Anagramm von '" + b2 + "'?"
Print StringTools.IsAnagram(b1, b2)

Print "Ist '" + c + "' ein Palindrom?"
Print StringTools.IsPalindrome(c)


Input ""
End








Type StringTools Abstract

Function Reverse:String(str:String)
Local rev:String = ""

For Local char:Int = str.Length Until 0 Step -1
rev :+ str[char - 1 .. char]
Next

Return rev
End Function


Function CountOccurences:Int(str:String, subStr:String)
Local occurences:Int = -1

Local pos:Int = 0
Repeat
occurences :+ 1
pos = str.Find(subStr, pos) + 1
Until pos = 0

Return occurences
End Function


Function IsAnagram:Int(str1:String, str2:String, ignoredChars:String = " ")
str1 = RemoveChars(str1, ignoredChars).ToLower()
str2 = RemoveChars(str2, ignoredChars).ToLower()

If str1.Length <> str2.Length Then Return False
For Local pos:Int = 0 Until str1.Length
Local foundpos:Int = str2.Find(str1[pos .. pos + 1])
If foundpos = -1 Then Return False
str2 = str2[.. foundpos] + str2[foundpos+1 ..]
Next

Return True
End Function


Function IsPalindrome:Int(str:String)
str = str.ToLower()
Return str = Reverse(str)
End Function


Function RemoveChars:String(str:String, chars:String)
For Local pos:Int = 0 Until chars.Length
Local char:String = chars[pos .. pos + 1]
str = str.Replace(char, "")
Next

Return str
End Function

End Type






Erklärung zu den Funktionen:

  • Reverse:String(str:String)
Geht den String zeichenweise rückwärts durch, und hängt das jeweilige Zeichen an einen anfangs leeren Ergebnisstring an. Simpel.

  • CountOccurences:Int(str:String, subStr:String)
Benutzt die String.Find-Methode aus BMax, welche die Position des ersten Vorkommens eines Teilstrings findet. Deren 2. Parameter (der festlegt, ab welcher Position gesucht werden soll) wird einfach immer auf ein Zeichen hinter den letzten Fund gesetzt, und das ganze so lange wiederholt, bis es keinen mehr gibt. Dabei wird mitgezählt.

  • IsAnagram:Int(str1:String, str2:String, ignoredChars:String = " ")
Die Strings werden zunächst in Kleinbuchstaben konvertiert und Leerzeichen (auf Wunsch auch beliebige andere) daraus entfernt.
Sind die Strings danach unterschiedlich lang, kann es sich schonmal um kein Anagramm handeln.
Ansonsten wird String 1 zeichenweise durchgegangen und das jeweilige Zeichen (wieder mit String.Find ermittelt) aus String 2 entfernt. Funktioniert das bis zum Ende, d.h. jedes der Zeichen wird im Rest von String 2 gefunden, handelt es sich um ein Anagramm, sonst nicht.

  • IsPalindrome:Int(str:String)
Trivial, da Reverse schon programmiert ist.

  • RemoveChars:String(str:String, chars:String)
Hilfsfunktion für IsAnagram. Benutzt String.Replace(Zeichen, "") für jedes einzelne Zeichen aus chars.
PC: Intel Core i7 @ 4x2.93GHz | 6 GB RAM | Nvidia GeForce GT 440 | Desktop 2x1280x1024px | Windows 7 Professional 64bit
Laptop: Intel Core i7 @ 4x2.00GHz | 8 GB RAM | Nvidia GeForce GT 540M | Desktop 1366x768px | Windows 7 Home Premium 64bit

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group