For Schleifen mit Array.. Gibt es da noch ähnliche Möglichkeiten?

  • Der unten angegebene Code geht noch weiter ist nur der Anfang davon.

    Man kann sich jedoch denken wie es weitergeht.

    Es wird jedes Mal eine For-Schleife mehr ausgeführt.

    Jetzt brauch ich nur iwie eine Möglichkeit dies dynamisch ausführen zu lassen.

    For-Schleife mit Array ( For $array[ $actuall ] = 1 to $x_beliebig ) wär meine Idee gewesen aber diese nimmt ja keine Arrays an.


    Hat jmd ne Idee?


    [autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 1 Buchstabe zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string )
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    If StringInStr( $trimmed_1, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 1 ) * 100
    Next

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 2 Buchstaben zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string ) - 1
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    For $act_letter2 = 1 to StringLen( $string ) - 2
    $trimmed_2 = _string_trim_mid( $trimmed_1, $act_letter2 )
    If StringInStr( $trimmed_2, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 2 ) * 100
    Next
    Next

    [/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 3 Buchstaben zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string ) - 1
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    For $act_letter2 = 1 to StringLen( $string ) - 2
    $trimmed_2 = _string_trim_mid( $trimmed_1, $act_letter2 )
    For $act_letter3 = 1 To StringLen( $string ) - 3
    $trimmed_3 = _string_trim_mid( $trimmed_2, $act_letter3 )
    If StringInStr( $trimmed_3, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 3 ) * 100
    Next
    Next
    Next

    [/autoit]
  • was willst du denn überhaupt erreichen? zeig doch mal ein bisschen mehr code,
    vllt gibts eine simplere lösung dafür, weil für die for schleife fällt mir gerade nix
    ein aber bin auch kein experte ;)

    gruß

    nova

  • Das wär der gesamte Code außer jetzt halt ohne das bei 4 Buchstaben, bei 5 Buchstaben, bei 6 ...

    Erreichen möchte ich das ich eine Funktion habe, welche einen String und einen 2. String einließt
    und errechnet zu wieviel % der 2. im 1. vorkommt.


    [autoit]

    ;~ Return:
    ;~ Prozentuale Übereinstimmung

    [/autoit][autoit][/autoit][autoit]

    Func _string_trim_mid( $string, $count )
    $trimmed = StringTrimLeft( $string, $count )
    Return StringLeft( $string, $count - 1 ) & $trimmed
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    MsgBox(0, "", _check_on_percent("is_string_a", "srng") )

    [/autoit][autoit][/autoit][autoit]

    Func _check_on_percent( $string, $search_string )

    [/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe von 100% bei String in Str gefunden ~~~~~~~~~~~~~~~~~~~~~~~~~~
    If StringInStr( $string, $search_string ) Then Return 100

    [/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 1 Buchstabe zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string )
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    If StringInStr( $trimmed_1, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 1 ) * 100
    Next

    [/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 2 Buchstaben zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string ) - 1
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    For $act_letter2 = 1 to StringLen( $string ) - 2
    $trimmed_2 = _string_trim_mid( $trimmed_1, $act_letter2 )
    If StringInStr( $trimmed_2, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 2 ) * 100
    Next
    Next

    [/autoit][autoit][/autoit][autoit]

    ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Übergabe bei 3 Buchstaben zu wenig ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    For $act_letter = 1 to StringLen( $string ) - 1
    $trimmed_1 = _string_trim_mid( $string, $act_letter )
    For $act_letter2 = 1 to StringLen( $string ) - 2
    $trimmed_2 = _string_trim_mid( $trimmed_1, $act_letter2 )
    For $act_letter3 = 1 To StringLen( $string ) - 3
    $trimmed_3 = _string_trim_mid( $trimmed_2, $act_letter3 )
    If StringInStr( $trimmed_3, $search_string ) Then Return StringLen( $search_string ) / ( StringLen( $search_string ) + 3 ) * 100
    Next
    Next
    Next
    EndFunc

    [/autoit]
  • also das würde ich anders lösen, ist vllt ne blöde lösung, aber wenn du nur
    wissen willst, wieviel exakt das selbe ist, dann würd ichs in etwa so machen:

    Spoiler anzeigen
    [autoit]


    #include <file.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;; $string = der erste string der geprüft wird
    ;; in der datei befindet sich der 2. string

    [/autoit] [autoit][/autoit] [autoit]

    $datei = FileOpen(@ScriptDir & "\test.txt", 16)

    [/autoit] [autoit][/autoit] [autoit]

    If $datei = -1 Then
    MsgBox(0, "Error", "Konnte Datei nicht öffnen.")
    Exit
    EndIf

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    $buchstabe = FileRead($datei, 1)
    If @error = -1 Then ExitLoop
    $string2 = $string2 & $buchstabe
    If StringInStr( $string, $string2 ) <> 0
    $anzahl = $anzahl + 1
    EndIf
    WEnd


    ;; $anzahl enthält die anzahl der von anfang beginnenden gleichen buchstaben
    ;; jetz nur noch die gesamtzahl der buchstaben auslesen, und % errechnen

    [/autoit] [autoit][/autoit] [autoit]

    FileClose($datei)

    [/autoit]

    PS: ich weiß ist sicher nicht die beste lösung aber so gehts :)

    gruß

    nova

  • Ich kann am besten mal ein kleines Bsp machen:

    Ich habe das Wort "string"

    5 von 6 Buchstaben sind richtig wenn das Wort lautet:
    "sring"
    "tring"
    "strin"
    usw...

    So geht das halt auch mit 4 Buchstaben, 3 , ..

    Deshalb geht das nicht so einfach. ;)

    Leider^^

    Zurückgeben würde die Func mir dann 83% des Wortes sind richtig.

  • ahh okay jetz versteh ich, ähm puh
    kurz überlegen ^^ grübel

    warum suchst du nicht einfach
    mit stringinstr ob es eine übereinstimmung
    gibt, wenn ja suchste die mit stringtrim
    raus und lässt die anzahl der zeichen
    bestimmten und vergleichst diese dann?

    gruß

    nova

  • Mit StringInStr findet man ja nur auch die vollständigen strings.

    In "String" würd ich also "tring", "ring", "Str", "trin", ... finden.

    "Stng", "rig", "Sing", .. würde diese Funktion jedoch nicht erkennen.

  • okay das auch noch? dann bin ich überfragt ^^ sry
    vllt fällt mir auf dem weg nach hause ja noch was ein,
    ansonsten gibts hier ja die experten die sicher rat wissen

    falls mir was einfällt meld ich mich nochmal

    gruß

    nova

    • Offizieller Beitrag

    Ich bastele mal schnell was.

    Edit:
    Es geht wie so oft hauptsächlich darum, einen guten Algorithmus zu finden, das Programmieren ist dann nicht mehr schwer:

    [autoit]

    Func _wordCompare($_word1, $_word2, $_caseSens)
    ; by peethebee (dont remove this!)

    Local $_good = 0
    Local $_bad = 0

    ; Wort1 durchlaufen
    For $_i = 1 to StringLen($_word1)
    ;~ ConsoleWrite(StringFormat("Testing letter %s", StringMid($_word1, $_i, 1)) & @CRLF)
    $_pos = StringInStr($_word2, StringMid($_word1, $_i, 1), $_caseSens)
    if ($_pos = 0) Then
    ; nicht in Wort2
    ;~ ConsoleWrite(StringFormat("Not in Word2, like %i more so far.", $_bad) & @CRLF)
    $_bad = $_bad + 1
    Else
    ; schon in Wort2 -> Entfernen, damit Buchstabenanzahl korrekt beachtet wird
    ;~ ConsoleWrite(StringFormat("In Word2, like %i more so far.", $_good) & @CRLF)
    $_good = $_good + 1
    $_word2 = StringLeft($_word2, $_pos - 1) & StringTrimLeft($_word2, $_pos)
    EndIf
    Next
    ; formatieren und zurückgeben
    Local $_retArray[4] = [$_good + $_bad, $_good, $_bad, StringFormat("%d", $_good / ($_good + $_bad) * 100)]
    Return $_retArray
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    ; Beispiel
    $ret = _wordCompare("AutoIt", "Autoit", true)
    ConsoleWrite("Compared AutoIt to Autoit with Case Sensitivity" & @CRLF)
    ConsoleWrite(StringFormat("Total number of characters: %i", $ret[0]) & @CRLF)
    ConsoleWrite(StringFormat("Number of common characters: %i", $ret[1]) & @CRLF)
    ConsoleWrite(StringFormat("Number of different characters: %i", $ret[2]) & @CRLF)
    ConsoleWrite(StringFormat("Number of common characters (percentage): %i", $ret[3]) & @CRLF)

    [/autoit]

    Beispielausgabe:

    Zitat

    Compared AutoIt to Autoit with Case Sensitivity
    Total number of characters: 6
    Number of common characters: 5
    Number of different characters: 1
    Number of common characters (percentage): 83

    peethebee

  • Aber auch hier tritt ein Problem auf.. und zwar

    [autoit]

    $ret = _wordCompare("AutoIt", "Autoit", true)

    [/autoit]


    und

    [autoit]

    $ret = _wordCompare("AtutIo", "Autoit", true)

    [/autoit]

    Die Fuktion wird bei beiden das selbe zurück geben.. 83%.

    Bei beiden kommen zwar 83% der Buchstaben vor, jedoch nicht 83% des Strings.

    Hoffe ich hab das verständlich ausgedrückt^^

    • Offizieller Beitrag

    Neuer Versuch:

    [autoit]

    Func _wordCompare($_word1, $_word2, $_caseSens)
    ; by peethebee (dont remove this!)

    Local $_good = 0
    Local $_bad = 0

    ; Wort1 durchlaufen
    For $_i = 1 to StringLen($_word1)
    ;~ ConsoleWrite(StringFormat("Testing letter %s", StringMid($_word1, $_i, 1)) & @CRLF)
    $_pos = StringInStr($_word2, StringMid($_word1, $_i, 1), $_caseSens)
    if ($_pos = 0) Then
    ; nicht in Wort2
    ;~ ConsoleWrite(StringFormat("Not in Word2, like %i more so far.", $_bad) & @CRLF)
    $_bad = $_bad + 1
    Else
    ; schon in Wort2 -> Entfernen, damit Buchstabenanzahl korrekt beachtet wird
    ;~ ConsoleWrite(StringFormat("In Word2, like %i more so far.", $_good) & @CRLF)
    $_good = $_good + 1
    $_word2 = StringLeft($_word2, $_pos - 1) & StringTrimLeft($_word2, $_pos)
    EndIf
    Next
    ; formatieren und zurückgeben
    Local $_retArray[4] = [$_good + $_bad, $_good, $_bad, StringFormat("%d", $_good / ($_good + $_bad) * 100)]
    Return $_retArray
    EndFunc

    [/autoit][autoit][/autoit][autoit][/autoit][autoit]

    Func _wordCompareInOrder($_word1, $_word2, $_caseSens)
    ; by peethebee (dont remove this!)

    Local $_good = 0
    Local $_bad = 0

    ; Wort1 durchlaufen
    For $_i = 1 to StringLen($_word1)
    ;~ ConsoleWrite(StringFormat("Testing letter %s", StringMid($_word1, $_i, 1)) & @CRLF)
    $_pos = StringInStr($_word2, StringMid($_word1, $_i, 1), $_caseSens)
    if ($_pos = 0) Then
    ; nicht in Wort2
    ;~ ConsoleWrite(StringFormat("Not in Word2, like %i more so far.", $_bad) & @CRLF)
    $_bad = $_bad + 1
    Else
    ; schon in Wort2 -> Entfernen, damit Buchstabenanzahl korrekt beachtet wird
    ;~ ConsoleWrite(StringFormat("In Word2, like %i more so far.", $_good) & @CRLF)
    $_good = $_good + 1
    $_word2 = StringTrimLeft($_word2, $_pos)
    EndIf
    Next
    ; formatieren und zurückgeben
    Local $_retArray[4] = [$_good + $_bad, $_good, $_bad, StringFormat("%d", $_good / ($_good + $_bad) * 100)]
    Return $_retArray
    EndFunc

    [/autoit][autoit][/autoit][autoit]

    $ret = _wordCompareInOrder("AtutIo", "Autoit", true)
    ConsoleWrite("Compared AutoIt to Autoit with Case Sensitivity" & @CRLF)
    ConsoleWrite(StringFormat("Total number of characters: %i", $ret[0]) & @CRLF)
    ConsoleWrite(StringFormat("Number of common characters: %i", $ret[1]) & @CRLF)
    ConsoleWrite(StringFormat("Number of different characters: %i", $ret[2]) & @CRLF)
    ConsoleWrite(StringFormat("Number of common characters (percentage): %i", $ret[3]) & @CRLF)

    [/autoit]

    peethebee

  • Diese sieht sehr gut aus ;) :)

    Ich werd mal sehn ob ich die so eingebaut bekomme wie gedacht.

    Edit:

    [autoit]

    $ret = _wordCompareInOrder("sing", "is_string_a", False)

    [/autoit]

    Gibt 100% zurück.. Glaub weil das ist der richtigen Reihenfolge vorhanden ist, oder? Also s..ing

    Aber das Wort sing stimmt ja nur zum Teil mit dem Teil string überein.

    Einmal editiert, zuletzt von hundi (31. März 2009 um 14:52)

  • Ich mach das bei meiner Funktion ja so das der sich immer den zu durchsuchenden String nimmt und immer einen Buchstaben rausschneidet ( Bei 1 Buchstabe zu wenig, bei den anderen dann halt entsprechend viele)

    bei dem Wort "String" würde er zb das so machen:
    tring
    Sring
    Sting
    Strng
    Strig <-
    Strin

    Wenn ich jetzt im Wort "String" das Wort "Strig" suche, wird er dieses finden.

    Die Func merkt.. aha.. ich musste einen Buchstaben aus dem Wort "String" rausschneiden um "Strig" zu finden, also ist 5/6 des Wortes richtig, da halt der eine Buchstabe fehlt.

    Mit mehr Buchstaben geht das halt genauso.


    Verstanden? :rolleyes: :D

  • Der nimmt dabei leider den gesamten String
    "is_string_a"
    und rechnet halt davon die Prozente.

    Wären bei "sing" halt 27%.

    sing kommt aber zu 4/6 vor, wären also 67%.

    __________
    Im Nachhinein soll halt ein falsch geschriebenes Wort rekonstruiert werden:

    sing => is_string_a => is_string_a => string

    Einmal editiert, zuletzt von hundi (31. März 2009 um 15:28)

  • Kann ich nicht.

    Der String könnte auch lauten: emuzikgrufweohStringEFjhjgpr,

    und dann hätte ich nichts mehr wo ich splitten kann.

    • Offizieller Beitrag

    Wenn auch der/die erste(n) oder der/die letze(n) Buchstaben fehlen kann/können und Wortanfänge nicht feststellbar sind, hast du ja keine Chance festzustellen, wo der gesuchte Teil anfängt.
    Zum Verständnis noch mal: In was für einem Tool willst du das verwenden (vielleicht geht es ja auch ganz anders)? Gegen welche Art von Liste vergleichst du die Eingabe (Wörterbuch)?

    peethebee