BPS #1: Buchstaben zählen - Auswertung

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

hamZta

Administrator

Betreff: BPS #1: Buchstaben zählen - Auswertung

BeitragMi, Jan 05, 2011 14:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Nachdem das Ende der ersten BPS etwas ungünstig auf die Feiertag gefallen ist, kommt nun verspätet aber doch der Auswertungsthread für die erste Aufgabe.

Aufgabenstellung

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
Ihr habt eine Woche Zeit, eure erste Aufgabe zu verbessern bzw. zu besprechen, dann kommt die nächste Aufgabe.

Viel Spaß!
Blog.

Ana

BeitragMi, Jan 05, 2011 14:16
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax: [AUSKLAPPEN]
Function Read_in:Int[](Datei$)
Local Array:Int[26]
Stream = ReadFile(datei)
While Not Eof(Stream)
Tex$ = Upper(ReadLine(stream))
length = Len(tex)
For i = 1 To length
b = Asc(Mid(tex,i,1)) - 65
If b > 0 And b < 25 Then array[b]:+ 1
Next
Wend
Return array
End Function

Function Give_Array(a[])
For i = 0 To a.lenght
Print Chr(i + 65) + " " + a[i]
Next
End Function

Give_Array(Read_in("Tex.txt"))



Oh die Erklärungen hätte ich fast vergessen und auch noch ins falsche Forum, naja was soll ich sagen ich war so aufgeregt Very Happy

Also hier die BB alternative

BlitzBasic: [AUSKLAPPEN]
Const Array_length = 26
Dim Array (Array_length)


Function Read_in(Datei$)
Stream = ReadFile(datei)
While Not Eof(Stream)
Tex$ = Upper(ReadLine(stream))
length = Len(tex)
For i = 1 To length
b = Asc(Mid(tex,i,1)) - 65
If b > 0 And b < 25 Then array(b)= array(b) + 1
Next
Wend
End Function

Function Give_Array()
For i = 0 To Array_length
Print Chr(i + 65) + " " + array(i)
Next
End Function

Read_in("Tex.txt")
Give_Array()


Also erstmal hab ich das Ganze in 2 Functionen unterteilt, die eine um die Buchstaben einzulesen und in einem Array ihre Anzahl zurückzugeben, die andere um ein Array auszugeben.

Die erste Funktion erwartet als übergabe die datei und liest dann solange bis sie das Ende der Datei erreicht hat Zeile für Zeile ein, und wandelt sie in Großbuchstaben um, damit kein Unterschied zwischen klein und großbuchstaben gemacht wird beim Zählen. Als nächstes wird die Länge des Strings gespeichert, man könnte sich die Zeile sparen und in die For Schleife tun, allerdings müsste dann für jeden durchlauf die function Len erneut angewendet werden, spart also rechenzeit, wenn man es so macht. (Und kostet halt 32bit speicher...)
Die For Schleife geht nun jeden Buchstaben ab mit Hilfe von dem Mid befehl, der immer eine Stringsequenz der größe eins an jedem einzelnen Punkt zurück gibt. Der Asc Befehl wandelt es von eine Buchstaben in seinen Unicode(?) Wert um. Die Buchstaben fangen beim Wert 65 an und gehen 26 Werte weiter also müssen sie zwischen 65 + 0 und 65 + 25 liegen. Die überprüfung ist dafür da, damit sonderzeichen oder z.B. das ä was irgendwo bei 196 rumfliegt nicht die Grenzen des Arrays überschreiten. Die Position im Alphabet ist nun in b gespeichert und wird im array erhöht wenn es denn ein Buchstabe ist. Anschließend wird das Array zurückgegeben.

Die zweite gibt einfach das erhaltene Array aus, und für jedes weitere Feld wird vorher noch das jeweilig Unicode Zeichen geschrieben, also in unserem fall das Alphabet.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine
  • Zuletzt bearbeitet von Ana am Mi, Jan 05, 2011 14:38, insgesamt 4-mal bearbeitet

hamZta

Administrator

BeitragMi, Jan 05, 2011 14:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielleicht liest du dir den Punkt "Diskussion" nochmal durch, Ana, und bearbeitest deinen Beitrag entsprechend.

hamZta
Blog.

Ana

BeitragMi, Jan 05, 2011 14:30
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie könnte ich dir was abschlagen Wink

ohje und es ist auch noch in der BB und nicht in der Bmax spalte gelandet ... na gut bis auf das array macht es nicht so den unterschied.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

The Shark

BeitragMi, Jan 05, 2011 16:13
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
Dim chars(25)

file=ReadFile(CommandLine())

If file
While Not Eof(file)
byte=ReadByte(file)
If byte >= 65 And byte <= 95 ;Großbuchstaben
chars(byte-65)=chars(byte-65)+1
ElseIf byte >= 97 And byte <= 122 ;Kleinbuchstaben
chars(byte-97)=chars(byte-97)+1
EndIf
Wend

CloseFile(file)

For i=0 To 25
Print Chr(i+65)+": "+chars(i)
Next
WaitKey
Else
Print "Datei kann nicht geöffnet werden"
EndIf
End


Per Commandozeile wird die Datei übergeben und Byteweise ausgelesen. Liegt das Byte in dem Bereich der Groß- oder Kleinbuchstaben, so wird das Array char an dem entsprechenden Index erhöht. Schlussendlich wird in einer Schleife das Ergebnis ausgegeben.

Diese Lösung hat den Vorteil, dass sie kurz, einfach und durch den verzicht auf Stringfunktionen schnell ist.
Rette deine Freiheit
 

Toasty

BeitragMi, Jan 05, 2011 16:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Code:
BlitzBasic: [AUSKLAPPEN]
Dim Buchstaben( 26 ) ;Array mit 26 Feldern für jeden Buchstaben anlegen


TextDatei = ReadFile( "Text.txt" ) ;Datei mit Text lesen

If TextDatei = 0 Then RuntimeError "Konnte die Textdatei nicht lesen!" ;Prüfen ob die Datei existiert

While( Not Eof( TextDatei ) ) ;Datei auslesen bis das Ende der Datei erreicht wurde
TextLinie$ = ReadLine( TextDatei ) ;Erste Zeile aus Datei auslesen


;Text bearbeiten damit NUR Buchstaben im String sind
TextLinie$ = Upper( TextLinie$ ) ;Alle Buchstaben in Groß-Buchstaben umwandeln
TextLinie$ = Replace( TextLinie$, " ", "" ) ;Leerzeichen entfernen
TextLinie$ = Replace( TextLinie$, "ä", "" ) ;Umlaut ä entfernen
TextLinie$ = Replace( TextLinie$, "ö", "" ) ;Umlaut ö entfernen
TextLinie$ = Replace( TextLinie$, "ü", "" ) ;Umlaut ü entfernen
TextLinie$ = Replace( TextLinie$, "ß", "" ) ;ß entfernen


For i = 1 To Len( TextLinie$ ) ;Schleife so oft wie die Länge des Strings durchführen
Buchstabe$ = Mid( TextLinie$, i, 1 ) ;den ersten Buchstaben AB dem Wert i auslesen

Buchstabe_ASC = Asc( Buchstabe$ ) ;Buchstabe in ASCII Wert umwandeln

Buchstabe_Nr = Buchstabe_ASC - 64 ;Der Wert vom Buchstaben "a" ist 65, daher Minus 64 damit die Nummer 1 oder größer ergibt

Buchstaben( Buchstabe_Nr ) = Buchstaben( Buchstabe_Nr ) + 1 ;Anzahl des Buchstabens plus 1
Next
Wend

CloseFile( TextDatei ) ;Datei mit Text schließen

Buchstaben_Datei = WriteFile( "Buchstaben.txt" ) ;Ausgangs Datei schreiben

WriteLine Buchstaben_Datei, "Anzahl der Buchstaben der Datei 'Text.txt':" ;Erste Zeile schreiben

For i = 1 To 26
Buchstabe$ = Chr( i + 64 ) ;ASCII Wert in String umwandeln
Buchstaben_Anzahl = Buchstaben( i ) ;Anzahl aus Array laden

Print Buchstabe + ": " + Buchstaben_Anzahl + " Stück" ;Buchstabe und Anzahl im Fenster darstellen

WriteLine Buchstaben_Datei, Buchstabe$ + ": " + Buchstaben_Anzahl + " Stück" ;Zeile mit Buchstabe und Anzahl der Buchstaben schreiben
Next

CloseFile( Buchstaben_Datei ) ;Ausgangs Datei schließen

Print "Lesen erfolgreich! Taste drücken um das Programm zu beenden."

WaitKey ;Auf Tastendruck warten

End ;Programm beenden

Wieso habe ich die Aufgabe auf diese Art gelöst?

Ich habe diese Aufgabe so gelöst, weil ich es am einfachsten finde, als erstes die Datei einzulesen, die einzelnen Buchstaben als ASCII Code in dem Array zu speichern und anschließend den Array Stück für Stück auszulesen, den ASCII Code in den Buchstaben zurück zu "verwandeln" und in der Datei mit der Anzahl zu speichern. In den Arrays sind (von A-Z) die Anzahl der Buchstaben gesammelt.

Ich hoffe das gilt als Beschreibung und/oder als Erklärung Sad

Gruß
Toasty
@AMD Phenom BE X4 2,5Ghz(Overclocked 2,61Ghz); 4GB DDR2; 512MB nVidia GeForce 8400gs; Win7 Home Premium 64bit
Lua for President!
 

FireStorm

BeitragMi, Jan 05, 2011 16:46
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]

datei=ReadFile ("Test1.txt")

If datei=0 Then RuntimeError("Konnte Datei nicht finden")
Dim Buchstabenanz(90)


While Not Eof(datei) ;Wiederholung der Schleife bis Daiteiende erreicht
zeile$=ReadLine(datei)
For I=1 To Len(zeile$) ;1 bis zeilenende
zeichen$=Mid$(zeile,I,1)
ascii=Asc(Zeichen$)



If ascii>=65 And ascii<=90 ;Großbuchstabenzähler
Buchstabenanz(ascii)=Buchstabenanz(ascii)+1
EndIf

If ascii>=97 And ascii<=122 ;Kleinbuchstabenzähler
Buchstabenanz(ascii-32)=Buchstabenanz(ascii-32)+1
EndIf


Next



Wend

For I=65 To 90
Print Chr$(I)+": "+Buchstabenanz(I)


Next


WaitKey

End



Ich habe die Aufgabe so gelöst wie ich es am einfachsten fand.
Die Datei wird eingelesen, dann jede Zeile einzeln auf Buchstaben überprüft.
Bei Kleinbuchstaben wird 32 vom ASCII-Code abgezogen um zu den Großbuchstaben dazugezählt
zu werden.
Der ASCII wird wieder in Zeichen umgewandelt und ausgegben.
Ich hoffe das war verständlich Cool .

an Ana:
Du hast 27 Buchstaben überprüft, die eckige Klammer war auch dabei Wink
statt

For i = 0 To Array_length

sollte es heißen

For i = 0 To Array_length-1
ASCII code für [ ist 91 (26+65)

InFaIN

BeitragDo, Jan 06, 2011 13:28
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
;Einstellungen
AppTitle "Line"
Graphics 640,480,8,2

;Startzeit für Zeitmessung
t=MilliSecs()

;Datei öffnen
stream = ReadFile("test.txt")

;Array für 26 Buchstaben
Dim zeichen(26)


;Widerhole solange die Datei nicht zuende ist
While Not Eof(stream)

;Nächste Zeile auslesen
zeile$ = ReadLine(stream)

;Widerhole bis zum Zeilenende
For i=1 To Len(zeile$)

;Nächstes Zeichen in ACSII lesen
acsii = Asc(Mid(zeile$,i,1))

;Wenn das Zeichen ein klein- oder Großbuchstabe ist:
If(acsii >=65 And acsii <= 90 Or acsii >= 97 And acsii <= 122)Then

;Großes A = 1
acsii = acsii - 64

;Falls es ein kleinbuchstabe ist: kleines a = 1
If( acsii > 26 ) Then acsii = acsii - 6 - 26

;Gefundenes Zeichen hochzählen
zeichen(acsii) = zeichen(acsii) + 1

EndIf

Next

Wend

;Alle Buchstaben ausgeben
For i=1 To 26

Print Chr$(i+64)+": "+zeichen(i)

Next

;Messung ende
t = MilliSecs()-t

;Messergbenis ausgeben
Print "Dauer: "+t

;Auf Tasteneingebe Warten
WaitKey

End



BlitzBasic: [AUSKLAPPEN]
;Einstellungen
AppTitle "Byte"
Graphics 640,480,8,2

;Startzeit für Zeitmessung
t = MilliSecs()

;Datei öffnen
stream = ReadFile("test.txt")

;Array für 26 Buchstaben
Dim zeichen(26)

;Widerhole solange die Datei nicht zuende ist
While Not Eof(stream)

;Nächstes Zeichen in ACSII einlesen
acsii = ReadByte(stream)

;Wenn das Zeichen ein klein- oder Großbuchstabe ist:
If(acsii >=65 And acsii <= 90 Or acsii >= 97 And acsii <= 122)Then

;Großes A = 1
acsii = acsii - 64

;Falls es ein kleinbuchstabe ist: kleines a = 1
If( acsii > 26 ) Then acsii = acsii - 32

;Gefundenes Zeichen hochzählen
zeichen(acsii) = zeichen(acsii) + 1

EndIf


Wend


;Alle Buchstaben ausgeben
For i=1 To 26

Print Chr$(i+64)+": "+zeichen(i)

Next

;Messung ende
t = MilliSecs()-t

;Messergbenis ausgeben
Print "Dauer: "+t

;Auf Tasteneingebe Warten
WaitKey

End




Ich habe das ganze zuerst wie in der Aufgabenstellung zeilenweise gelöst. Ich fasse klein und Großbuchstaben zusammen, da es nicht anders verlangt wurde. Danach habe ich mich gefragt warum eigentlich kompliziert Zeilenweise auslesen? Also habe ich das ganze Byteweise umgeschrieben und noch einen Gewschwindigkeitstest durchgeführt. Bytweise ist deutlich shcneller und kürzer vom Code.

Wenn Fragen zum Code sind, einfach fragen.....

Eingeproggt

BeitragDo, Jan 06, 2011 14:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Hmm.. zuerst dachte ich, ich warte ein wenige bis da ein paar Beiträge zusammen gekommen sind... aber wenn ich das richtig sehe, hat sich hier nich kein "Beginner" gemeldet sondern nur Leute die handfeste Lösungen präsentiert haben... von der Idee her genauso wie meine.

BlitzBasic: [AUSKLAPPEN]
;Array, in welchem der "Zählerstand" für jeden Buchstaben gespeichert wird
;Wird in der Funktion noch dimensioniert (ja das geht Wink )
Dim charCount(0)

;Hier kann man umstellen, ob man die Datei zeilenweise oder Byteweise bearbeiten will.
;Das macht keinen Unterschied im Ergebnis, aber es sind 2 verschiedene Herangehensweisen.
Const MODE_READLINE=1
Const MODE_READBYTE=2

AnalyseText("Test.txt",MODE_READBYTE)
;AnalyseText("Test.txt",MODE_READLINE)

WaitKey()
End

Function AnalyseText(file$,mode)
;Array zurücksetzen (einfach neu dimensionieren -> lauter 0en im Array)
Dim charCount(25)
;Die Variablen brauchen wir nachher - jetzt mal sauber deklarieren
Local txt$,char$,ascii
;Datei zum Lesen öffnen
Local reader=ReadFile(file$)

If reader=0 Then
;Wenn Datei nicht geöffnet werden kann
RuntimeError(file$+" konte nicht geöffnet werden")
Else
;Datei vollständig auslesen
While Not Eof(reader)

If mode=MODE_READBYTE Then
;Byteweise einlesen:
ascii=ReadByte(reader)

;Kleinbuchstaben selber in Großbuchstaben wandeln - siehe ASCII-Table
If ascii>=97 And ascii<=122 Then
ascii=ascii-32
EndIf

;Wenn Buchstabe, dann betreffenden Array-Eintrag um 1 erhöhen
If ascii>=65 And ascii<=90 Then
charCount(ascii-65)=charCount(ascii-65)+1
EndIf
EndIf

If mode=MODE_READLINE Then
;zeilenweise auslesen
txt$=ReadLine(reader)
;In Großbuchstaben wandeln
txt$=Upper(txt$)

;gesamte Zeile Zeichen für Zeichen durchlaufen
For i=1 To Len(txt$)
;Zeichen
char$=Mid(txt$,i,1)
;ASCII-Wert des Zeichens
ascii=Asc(char$)

;Wenn Buchstabe, dann betreffenden Array-Eintrag um 1 erhöhen
If ascii>=65 And ascii<=90 Then
charCount(ascii-65)=charCount(ascii-65)+1
EndIf
Next
EndIf
Wend
;Datei sauber schließen
CloseFile reader
EndIf

;Ausgabe im Debuglog (daher den Code immer im Debug-Modus ausführen!)
For i=0 To 25
DebugLog Chr(i+65)+": "+charCount(i)
Next
End Function


Auch ich habe es einmal Zeilenweise und einmal Byteweise probiert. Dabei immer "in Großbuchstaben umgedacht" und Sonderzeichen einfach nicht berücksichtigt. Das "besondere" an meiner Lösung ist, dass es "2 in 1" ist - in einer Funktion, man wählt die Arbeitsweise durch den letzten Parameter "mode" aus. Finde ich praktischer, aber ist wohl Geschmackssache. (Da meine Variante theoretisch langsamer ist, als eine 2. "komplette" Funktion.)

Wie dem auch sei, ich hab mich bemüht, den Code schön zu kommentieren und es hat mir Spass gemacht!

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9

hazumu-kun

BeitragDo, Jan 06, 2011 18:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Meine Lösung:

BlitzBasic: [AUSKLAPPEN]
; ###### Buchstaben zählen für den BPS #1
; #### Autor: Viken Emesh
; ******

; #### Variablen und Felder
Global char_len
Dim Char(0)

Dim Count(25)
; ****

; #### Hauptprogramm
LoadText()
CountChars()
PrintCount()

Input("Enter Drücken zum Beenden...")
End
; ****

; #### Funktionen
Function LoadText()
; Lädt Text aus einer Datei und speichert ihn in das Array "Char"
Local txt$
Local file$
Local hndl_file
Local i

file$= RequestFile$ ("Datei mit Text auswählen","*",0,"")
If FileType(file$)=1 Then
hndl_file= ReadFile(file$)
If hndl_file Then
While Not Eof(hndl_file)
txt$= txt$+ReadLine$(hndl_file)
Wend
CloseFile hndl_file

txt$=Upper$(txt$)
char_len= Len(txt$)
Dim Char(char_len-1)

For i= 0 To char_len-1
Char(i)= Asc(Mid$(txt$,i+1,1))
Next
Else
RuntimeError ("Fehler beim Laden der Datei!")
EndIf
Else
RuntimeError ("Keine Datei gewählt!")
EndIf
End Function

Function CountChars()
; Zählt die Häufigkeit jedes Buchstaben und speichert sie im Array "Count"
Local i

For i= 0 To char_len-1
If Char(i)<91 And Char(i)>64 Then
Count(Char(i)-65)= Count(Char(i)-65)+1
EndIf
Next
End Function

Function PrintCount()
; Gibt die Zähler für jeden Buchstaben aus.
Local i

For i= 0 To 25
Print Chr$(i+65)+": "+Count(i)
Next
End Function
; ****

Im Nachhinein finde ich es nicht sonderlich intelligent gelößt den gesammten Text in einem Dim zwischenzuspeichern, das hat mir aber eine sehr schöne Strukturierung über die 3 Funktionen ermöglicht.

Der Code funktioniert bis auf eine kleine Ausnahme mit jedem BlitzBasic Compiler:
Nicht-BlitzPlus-User müssen folgende Zeile in der Funktion "LoadText()" noch umschreiben:
Code: [AUSKLAPPEN]
file$= RequestFile$ ("Datei mit Text auswählen","*",0,"")

Entweder setzt man file$ konstant oder arbeitet mit Input().

LG Hazumu.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

Xeres

Moderator

BeitragDo, Jan 06, 2011 21:57
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Toasty:
BlitzBasic: [AUSKLAPPEN]
Dim Buchstaben( 26 ) ;Array mit 26 Feldern für jeden Buchstaben anlegen
Das Array hat 27 Felder - nicht vergessen, dass Feld 0 auch existiert!
Beim Beispieltext ist "ä" mit "ae" umschrieben, daher hätte ich mit Replace entsprechend verfahren, anstatt die Zeichen komplett zu löschen.

@ hazumu-kun:
Ich finde die Strukturierung in Funktionen gut gelöst. Manchmal ist Übersicht wichtiger als kleiner Code. Und er lässt sich in dieser Form fix erweitern; ein fertiges Array lässt sich durch die Funktionale Trennung schnell mit andere Analysen erweitern.

Schön, dass die Veranstaltung offenbar auf Interesse stößt Smile
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)
 

BIG BUG

BeitragFr, Jan 07, 2011 4:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine andere Möglichkeit wäre mit ReadBytes die Datei in eine Bank zu verfrachten und diese dann durchzugehen. Entspricht natürlich nicht ganz der Anforderung mit dem zeilenweisen Einlesen könnte insgesamt aber sogar noch einen Tick schneller als mit ReadByte sein...
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)
 

exastion

BeitragFr, Jan 07, 2011 18:33
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
;Aufloesung<<<<<<<<<<<<<
Graphics 640,480,16,2
;Aufloesung<<<<<<<<<<<<<

Dim ASCII(25) ;Array mit 26 Stellen, für die Buchstaben
Global Datei$, filein%, txt%, i%

;Welcher Text soll gezaehlt werden<<<<<<<<<<<<<<<<<<<<<<<<

Print "Welche Datei? (Nur *.txt)"
Print

Datei$=Input$(">>> ")

;Welcher Text soll gezaehlt werden<<<<<<<<<<<<<<<<<<<<<<<<

filein=ReadFile(Datei + ".txt") ;Oeffnen der Datei

;Hauptschleife

While Not Eof(filein) ;Solange das End der Datei nicht erreicht

txt%=ReadByte(filein) ;Jedes Byte einlesen

For i=0 To 25 ;For-Schleife für alle Buchstaben des Alphabetes

Select txt ;Eine Select-Abfrage für die Buchstaben

Case i+65 Or i+97 ;Überprüfen der Buchstaben

ASCII(i)=ASCII(i)+1 ;Erweiter des Arrays

End Select

Next

Wend

CloseFile(filein) ;Schliessen der Datei

Cls

For i=0 To 12

Text 15,FontHeight()*i+2,Chr(i+97) + " : " + Len(ASCII(i)) ;Ausgabe

Next

For i=0 To 12

Text 100,FontHeight()*i+2,Chr(i+110) + " : " + Len(ASCII(i))

Next



WaitKey()

End


Hallo, ich habe es am Anfang mit Zeilenweiser Einlesung probiert, bin aber daran gescheitert. Deshalb habe ich das ganze mit Bytes gemacht.

Ich habe den ganzen Code kommentiert.
MfG exastion

Bitte verbessert mich, wenn ich was falsches schreibe.

hazumu-kun

BeitragFr, Jan 07, 2011 18:59
Antworten mit Zitat
Benutzer-Profile anzeigen
@ Xeres
Die Idee mit der Erweiterbarkeit war mir auchschon gekommen.
Man könnte nicht nur den Text noch analysieren, sondern über die Zähler der Buchstaben eine Cäsar Verschlüsselung knacken.
Warum kann es keine omnipotente Macht geben?
Weil diese omnipotente Macht in der Lage sein müsste, einen so schweren Stein zu schaffen, dass sie ihn nicht heben kann
-> nicht omnipotent

Eingeproggt

BeitragFr, Jan 07, 2011 19:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Der THread soll ja auch zum Diskutieren und Vorschläge machen genutzt werden, daher:
@exastion:

Mir gefällt, dass du glaub ich der einzige bist, der die Ausgabe mit Text macht.
Außerdem hast du all deine Variablen am Anfang deklariert (das gefällt mir, siehe mein Code Wink )

Aber der "Hauptteil" der die eigentliche Arbeit macht gefällt mir ehrlich gesagt weniger, er kommt mir zu umständlich vor.

BlitzBasic: [AUSKLAPPEN]
For i=0 To 25						;For-Schleife für alle Buchstaben des Alphabetes

Select txt ;Eine Select-Abfrage für die Buchstaben

Case i+65 Or i+97 ;Überprüfen der Buchstaben

ASCII(i)=ASCII(i)+1 ;Erweiter des Arrays

End Select

Next


Also wenn man eh nur auf etwas bestimmtes Abfragen möchte, würde ich if eher empfehlen, statt Select-Case. Aber überhaupt. Du schaust bei jedem Zeichen ob es einem der 26 zu zählendem entspricht.
Das ist relativ viel Arbeit.
BlitzBasic: [AUSKLAPPEN]
ASCII(txt-65)=ASCII(txt-65)+1

würde es eigentlich schon tun. Ganz ohne Schleife und dem i. Dann muss man allerdings nochmal eine Überprüfung für Kleinbuchstaben machen. Viele Wege führen nach Rom und ich bin froh, auch mal einen andere gesehen zu haben. Auch wenn ich ihn wie gesagt für zu umständlich halte.

mfG, Christoph.
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9
 

exastion

BeitragFr, Jan 07, 2011 20:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie gesagt, ich bin noch ein Anfänger, aber Danke für das Lob.

Was den Hauptteil betrifft, habe ich mich nicht mehr sehr lange damit beschäftigt, als ich ihn bis fertig hatte.
MfG exastion

Bitte verbessert mich, wenn ich was falsches schreibe.

JimBobBalou

BeitragSa, Jan 08, 2011 1:34
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzBasic: [AUSKLAPPEN]
Graphics 640, 480, 0, 2
AppTitle "BPS #1: Buchstaben zählen, JimBobBalou"

Dim zaehler ( 25 ) ;Array definieren
datei = ReadFile( "test.txt" ) ;Datei mit dem Text laden

Repeat ;Schleife für die Textzeilen
textzeile$ = Lower$( ReadLine$( datei ) ) ;Textzeile einlesen und alle Buchstaben klein machen
For buchstabe = Asc("a") To Asc("z") ;Vorgang für jeden Buchstaben von a bis z wiederholen
position = 0
Repeat
position = Instr( textzeile$, Chr$( buchstabe ), position+1 ) ;Nach Buchstaben suchen
If position <> 0 Then zaehler( buchstabe-Asc("a") ) = zaehler( buchstabe-Asc("a") ) + 1 ;Zähler erhöhen, wenn der Buchstabe gefunden wurde
Until position = 0 ;Wiederholen, bis alle Chr$(buchstabe) in der Zeile gezählt wurden
Next
Until Eof ( datei ) ;Schleife beenden, wenn alle Zeilen ausgelesen wurden
CloseFile datei ;Datei schließen

For n = 0 To 25 ;Ergebnisse ausgeben
Print Upper$( Chr$( n + Asc("a") ) ) + ": " + zaehler( n )
Next

WaitKey()
End

Jede Textzeile wird eingelesen un für jeden Buchstaben wird überprüft, wie oft er in dieser Textzeile vorhanden ist. Am Ende werden die Ergebnisse mit Print ausgegeben.

Nova

BeitragFr, Jun 01, 2012 16:21
Antworten mit Zitat
Benutzer-Profile anzeigen
(Ja, ich weiß, dass diese BPS schon lange vorbei ist. Allerdings bin ich persönlich der Meinung, dass man auch nachher noch seinen Code hinzufügen kann. Je mehr desto besser. Wink)

Mein Programm funktioniert, indem man einfach die auszulesende Textdatei auf das Programm "raufzieht". Drag&Drop im Explorer, falls das jemandem etwas sagt. Wink
Daher ist es auch nicht so leicht, es direkt im Blitz-Editor zu testen. Um dies zu erreichen, müsst ihr den Pfad eurer Datei unter Program -> Program Command Line... erstmal einfügen. Dann funktioniert es. Wink

Wie bin ich die Sache angegangen? Erst mal die klassischen Überlegungen: Ich brauche für jeden Buchstaben Platz, um zu speichern, wie oft er vorkam. Ein Integer-Array (Ganzzahlen-Feld) mit 26 Einträgen ist da genau das richtige.
Um herauszufinden, welchen Buchstaben ich da denn gerade ausgelesen habe, nutze ich die ASCII-Werte. Dazu muss man halt wissen, dass alle Buchstaben in der richtigen Reihenfolge gespeichert werden. Also erst kommt A, dann B, dann C... bis Z am Ende. Um zu wissen, an welchem Punkt denn nun das Alphabet beginnt (ASCII enthält mehr als nur Buchstaben), setzte ich einfach den ASCII-Wert von "A" als Quasi-Konstante. (Dieser ist normalerweise 65).
Mit diesem Wert kann man jetzt den Rest machen. So kann man leicht herausfinden, ob das Symbol, dass man gerade eingelesen hat, denn auch ein Buchstabe ist. Sollte sich der ASCII-Wert des Symbols zwischen ("A") und ("A"+26) befinden, dann haben wir einen Buchstaben. ("A"+26 ergibt dabei "Z")

Der Rest ist simples Textdatei auslesen und Werte verarbeiten. Die Befehle ReadLine, Left, Right und Len und Eof sind dabei recht hilfreich. Wink

Oh, achja: Es wird nur die Häufigkeit von Buchstaben ausgegeben, die auch vorkommen. Sollte der Text also kein Q enthalten, wird bei der Ausgabe auch kein Q erwähnt.
BlitzBasic: [AUSKLAPPEN]
; Buchstaben zählen
; Dieses Programm zählt alle Buchstaben (a bis z, A bis Z) in einer ihm übergeben Datei.
; Danach wird das Ergebnis, also die Häufigkeitsverteilung der Buchstaben, ausgegeben.

Graphics 800, 600, 0, 2
Local ASCII = Asc ("A") ; Erstelle eine Konstante mit dem ASCII-Wert von "A".
Local dateiname$ = CommandLine () ; Speichere alle übergeben Parameter in der Variable "dateiname".

If dateiname = "" Then ; Wenn keine Datei übergeben wurde, gib diese Fehlermeldung aus:
Print "Bitte ziehen sie eine Textdatei auf das Symbol dieses Programmes."
ElseIf FileType (dateiname) <> 1 ; Wenn der übegebene Text kein gültiger Dateiname ist:
Print "Bitte ziehen sie eine Textdatei auf das Symbol dieses Programmes."
Print "Bitte übergeben sie nicht selbsttätig andere Werte oder ziehen Ordner."
Else
Local datei = ReadFile(dateiname) ; Die Datei wird ausgelesen.
; Array für die Buchstaben:
Dim buchstabenfeld(25) ; Wir haben 26 Buchstaben, also von 0 bis 25
While Not Eof(datei) ; Ist das Ende der Datei erreicht? Wenn nein, wiederhole
zeile$ = Upper (ReadLine (datei)) ; Lese eine Zeile aus und wandle alle Zeichen in Großbuchstaben um.

While Len (zeile) > 0 ; Gehe jetzt die Zeile durch und speichere jeden Buchstaben.

buchstabe$ = Left(zeile, 1)
If (Asc (buchstabe) <= (ASCII + 26)) And (Asc (buchstabe) >= ASCII) Then ; WENN es ein Buchstabe ist...
; ...erhöhe das Feld mit dem Buchstaben um 1
buchstabenfeld(Asc (buchstabe) - ASCII) = buchstabenfeld(Asc (buchstabe) - ASCII) +1
EndIf
zeile = Right (zeile, Len (zeile) -1) ; Lösche den Buchstaben ganz links
Wend
Wend

; Und nun folgt die Ausgabe:
Local ausgegeben = 0 ; Anzahl, wie viele verschiedene Buchstaben registriert wurden.

For i = 0 To 25 ; Gehe alle Inhalt von "buchstabenfeld" durch
If buchstabenfeld(i) > 0 Then
Print Chr (i + ASCII) + ": " + buchstabenfeld(i) + "x" ; Ausgabe
ausgegeben = ausgegeben +1
EndIf
Next
If ausgegeben = 0 Then
Print "Die Datei enthielt keine Buchstaben (a bis z, A bis Z)!"
EndIf
EndIf

Print "Tastendruck zum Beenden des Programms"
WaitKey
End
AMD Athlon II 4x3,1GHz, 8GB Ram DDR3, ATI Radeon HD 6870, Win 7 64bit

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group