Nur in bestimmtem Fall den String trennen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

Aufgrund der Corona-Krise: Die Veröffentlichung von Stellenangeboten und -gesuchen ist bis 31.12.2020 kostenfrei. Das beinhaltet auch Angebote und Gesuche von und für Freischaffende und Selbstständige.

  • Michael schrieb:

    Wenn der Scanner ein (,+ oder ) gefunden hat, musst du die scanLocation eins weiter setzen, sonst findet der das selbe Zeichen immer wieder.


    einfach + 1 oder in wie fern weiter setzen? :)

    So klappt es auf jeden fall nicht... der läuft ab der ersten Klammer im String auf der Stelle und hört nicht mehr auf...

    Quellcode

    1. ​NSUInteger oldLocation = [scanner scanLocation];
    2. [scanner setScanLocation:oldLocation++];

    _____________________________________________

    MCDan schrieb:

    Die Logik von NSScanner erschliesst sich mir teilweise auch nicht so recht. Der scannt teilweise die wildesten Sachen.

    Ich würde es auch wie Claus direkt Old-School lösen. Dies sollte dann etwa so aussehen:

    Quellcode

    1. NSMutableString *result = [NSMutableString string];
    2. int bracketLevel = 0;
    3. int i = 0;
    4. while (i < masskette.length)
    5. {
    6. NSString *nextChar = [masskette substringWithRange:NSMakeRange(i, 1)];
    7. if ([@"(" isEqualToString:nextChar])
    8. bracketLevel++;
    9. else if ([@")" isEqualToString:nextChar])
    10. bracketLevel--;
    11. else if ([@"+" isEqualToString:nextChar] && bracketLevel == 0)
    12. [result appendString:@"\n"];
    13. [result appendString:nextChar];
    14. i++;
    15. }
    16. NSLog(@"result:%@",result);
    Alles anzeigen


    SORRY: Wegen dem Doppelpost...

    Ich bin ja schon froh dass ich nicht alleine leicht aufm Schlauch stehe :D
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von DBocksteger ()

  • gritsch schrieb:

    MCDan schrieb:

    Die Logik von NSScanner erschliesst sich mir teilweise auch nicht so recht. Der scannt teilweise die wildesten Sachen.

    Ich würde es auch wie Claus direkt Old-School lösen.


    und warum "substringWithRange" und nicht "characterAtIndex"?
    ersteres ist ja komplizierter (zu schreiben und zu lesen) und auch noch langsamer ;)

    Würde sicherlich auch gehen. Programmierung ist ja keine Einbahnstraße und es gibt ja auch mehrere Wege nach Rom. ;)
  • Michael schrieb:

    DanielBocksteger95 schrieb:

    einfach + 1 oder in wie fern weiter setzen?

    Da du das Zeichen ja schon in character als NSString hast, einfach ein beherztes

    Quellcode

    1. [scanner scanString:character intoString:NULL];


    Nun schaut mein Code aktuell so aus.

    Quellcode

    1. while (![scanner isAtEnd]) {
    2. NSString* chunk;
    3. if ([scanner scanUpToCharactersFromSet:klammerPlusSet intoString:&chunk]) {
    4. NSLog(@"Scanned chunk:%@", chunk);
    5. if ([scanner scanLocation] < [masskette length]) {
    6. NSString *character = [masskette stringAtIndex:[scanner scanLocation]];
    7. if ([character isEqualToString:@"("]) {
    8. bracketLevel++;
    9. }
    10. else if ([character isEqualToString:@")"]) {
    11. bracketLevel--;
    12. }
    13. else if ([character isEqualToString:@"+"]) {
    14. if (bracketLevel == 0) {
    15. [row appendString:@"\r\n"];
    16. }
    17. }
    18. [row appendString:chunk];
    19. [scanner scanString:character intoString:NULL];
    20. }
    21. else if ([scanner scanLocation] == [masskette length]) {
    22. [row appendString:chunk];
    23. }
    24. else {
    25. NSLog(@"Index %i liegt außerhalb der Maßkette (%i Zeichen lang)!", [scanner scanLocation], [masskette length]);
    26. }
    27. }
    28. if (row) {
    29. [rows addObject:row];
    30. }
    31. }
    Alles anzeigen


    Mit folgendem Code Stück war allerdings die Endlosschleife behoben.

    Quellcode

    1. [scanner scanUpToString:@"" intoString:NULL];
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von DBocksteger ()

  • Habe nun mal alle "Schritte" in der Ausgabe durchnummeriert.

    Meine aktuelle Methode:

    Quellcode

    1. ​+ (NSString *)GetMasskettenZeilenGetrennt:(NSString *)masskette
    2. {
    3. int bracketLevel = -1;
    4. masskette = [masskette stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
    5. NSScanner *scanner = [NSScanner scannerWithString:masskette];
    6. NSCharacterSet *klammerPlusSet = [NSCharacterSet characterSetWithCharactersInString:@"()+"];
    7. NSMutableString *row = [NSMutableString new];
    8. NSLog(@"Maßkette:%@", masskette);
    9. while (![scanner isAtEnd]) {
    10. NSString* chunk;
    11. if ([scanner scanUpToCharactersFromSet:klammerPlusSet intoString:&chunk]) {
    12. NSLog(@"Scanned chunk:%@ %i vs. %i", chunk, [scanner scanLocation], [masskette length]);
    13. NSLog(@"1. ScanUpTo ausgeführt");
    14. if ([scanner scanLocation] < [masskette length]) {
    15. NSString *character = [masskette stringAtIndex:[scanner scanLocation]];
    16. NSLog(@"2. Mitten in der Maßkette");
    17. if ([character isEqualToString:@"("]) {
    18. NSLog(@"3.1 Öffnende Klammer entdeckt");
    19. bracketLevel++;
    20. }
    21. else if ([character isEqualToString:@")"]) {
    22. NSLog(@"3.2 Schließende Klammer entdeckt");
    23. bracketLevel--;
    24. }
    25. else if ([character isEqualToString:@"+"]) {
    26. NSLog(@"3.3 Plus entdeckt");
    27. if (bracketLevel == 0) {
    28. [row appendString:@"\r\n"];
    29. }
    30. }
    31. [row appendString:chunk];
    32. [scanner scanString:character intoString:NULL];
    33. }
    34. else if ([scanner scanLocation] == [masskette length]) {
    35. NSLog(@"4. Ende erreicht");
    36. [row appendString:chunk];
    37. }
    38. else {
    39. NSLog(@"Index %i liegt außerhalb der Maßkette (%i Zeichen lang)!", [scanner scanLocation], [masskette length]);
    40. }
    41. }
    42. else {
    43. NSLog(@"Endlosschleife....");
    44. }
    45. }
    46. return row;
    47. }
    Alles anzeigen


    Ausgabe sieht wie folgt aus...

    Quellcode

    1. ​2014-06-30 14:44:56.853 xy[5536:60b] Maßkette:0,21 m * ((2,62 m + 2,62 m) / 2)
    2. 2014-06-30 14:44:56.853 xy[5536:60b] Scanned chunk:0,21 m * 9 vs. 32
    3. 2014-06-30 14:44:56.853 xy[5536:60b] 1. ScanUpTo ausgeführt
    4. 2014-06-30 14:44:56.854 xy[5536:60b] 2. Mitten in der Maßkette
    5. 2014-06-30 14:44:56.854 xy[5536:60b] 3.1 Öffnende Klammer entdeckt
    6. 2014-06-30 14:44:56.854 xy[5536:60b] Endlosschleife....
    7. 2014-06-30 14:44:56.855 xy[5536:60b] Endlosschleife....
    8. 2014-06-30 14:44:56.855 xy[5536:60b] Endlosschleife....
    9. 2014-06-30 14:44:56.855 xy[5536:60b] Endlosschleife....
    10. 2014-06-30 14:44:56.855 xy[5536:60b] Endlosschleife....
    11. 2014-06-30 14:44:56.856 xy[5536:60b] Endlosschleife....
    12. 2014-06-30 14:44:56.856 xy[5536:60b] Endlosschleife....
    13. 2014-06-30 14:44:56.856 yx[5536:60b] Endlosschleife....
    14. 2014-06-30 14:44:56.857 xy[5536:60b] Endlosschleife....
    15. 2014-06-30 14:44:56.857 xy[5536:60b] Endlosschleife....
    16. 2014-06-30 14:44:56.857 yx[5536:60b] Endlosschleife....
    17. ...
    Alles anzeigen


    Man sieht, er hört nachd er ersten Klammer die er findet einfach auf.. :(
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io
  • Ich habe mit das jetzt nicht im Detail angesehen. Hier mal eine funktionierende NSScanner Version.

    Quellcode

    1. int main(int argc, const char * argv[])
    2. {
    3. @autoreleasepool {
    4. NSString *massKette = @"0,21 m * ((2,62 m + 2,62 m) / 2)";
    5. NSScanner *scanner = [NSScanner scannerWithString:massKette];
    6. NSCharacterSet *klammerPlusSet = [NSCharacterSet characterSetWithCharactersInString:@"()+"];
    7. NSInteger bracketLevel = 0;
    8. NSMutableString *result = [NSMutableString string];
    9. [scanner setCharactersToBeSkipped:nil];
    10. while (![scanner isAtEnd]) {
    11. NSString *chunk;
    12. [scanner scanUpToCharactersFromSet:klammerPlusSet intoString:&chunk];
    13. if (chunk) {
    14. [result appendString:chunk];
    15. }
    16. if (![scanner isAtEnd]) {
    17. NSUInteger scanLocation = [scanner scanLocation];
    18. UniChar uniChar = [massKette characterAtIndex:scanLocation];
    19. if (uniChar == '(') {
    20. bracketLevel++;
    21. }
    22. else if (uniChar == ')') {
    23. bracketLevel--;
    24. }
    25. else if (bracketLevel == 0) {
    26. [result appendString:@"\n"];
    27. }
    28. [result appendFormat:@"%C", uniChar];
    29. [scanner setScanLocation:scanLocation + 1];
    30. }
    31. }
    32. NSLog(@"%@", result);
    33. }
    34. return 0;
    35. }
    Alles anzeigen
  • Michael schrieb:

    Ich habe mit das jetzt nicht im Detail angesehen. Hier mal eine funktionierende NSScanner Version.

    Quellcode

    1. int main(int argc, const char * argv[])
    2. {
    3. @autoreleasepool {
    4. NSString *massKette = @"0,21 m * ((2,62 m + 2,62 m) / 2)";
    5. NSScanner *scanner = [NSScanner scannerWithString:massKette];
    6. NSCharacterSet *klammerPlusSet = [NSCharacterSet characterSetWithCharactersInString:@"()+"];
    7. NSInteger bracketLevel = 0;
    8. NSMutableString *result = [NSMutableString string];
    9. [scanner setCharactersToBeSkipped:nil];
    10. while (![scanner isAtEnd]) {
    11. NSString *chunk;
    12. [scanner scanUpToCharactersFromSet:klammerPlusSet intoString:&chunk];
    13. if (chunk) {
    14. [result appendString:chunk];
    15. }
    16. if (![scanner isAtEnd]) {
    17. NSUInteger scanLocation = [scanner scanLocation];
    18. UniChar uniChar = [massKette characterAtIndex:scanLocation];
    19. if (uniChar == '(') {
    20. bracketLevel++;
    21. }
    22. else if (uniChar == ')') {
    23. bracketLevel--;
    24. }
    25. else if (bracketLevel == 0) {
    26. [result appendString:@"\n"];
    27. }
    28. [result appendFormat:@"%C", uniChar];
    29. [scanner setScanLocation:scanLocation + 1];
    30. }
    31. }
    32. NSLog(@"%@", result);
    33. }
    34. return 0;
    35. }
    Alles anzeigen


    Danke dir ebenfalls für die Mühe! Habe jetzt aber vorerst zu MCDans Lösung gegriffen, da diese doch deutlich nachvollziehbarer ist...
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io
  • DanielBocksteger95 schrieb:



    Danke für die Antworten und den Link!

    Ich würde aber behaupten, das ein Formelparser zum Trennen der Zeilen etwas overpowered wäre? Ich schaue aber mal in den Artikel rein, um eine etwas abgespecktere Version zu implementieren.


    Du willst eine Formel verstehen. Ein Formelparser ist daher per Definition das richtige Werkzeug. Und wozu selbst etwas Abgestecktes implementieren, wenn es das Ganze doch schon fertig gibt?
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?
  • Amin Negm-Awad schrieb:

    DanielBocksteger95 schrieb:



    Danke für die Antworten und den Link!

    Ich würde aber behaupten, das ein Formelparser zum Trennen der Zeilen etwas overpowered wäre? Ich schaue aber mal in den Artikel rein, um eine etwas abgespecktere Version zu implementieren.


    Du willst eine Formel verstehen. Ein Formelparser ist daher per Definition das richtige Werkzeug. Und wozu selbst etwas Abgestecktes implementieren, wenn es das Ganze doch schon fertig gibt?


    Naja "verstehen" würde ich nicht sagen... ich suche einfach nur nach "+" Zeichen die entweder innerhalb oder außerhalb von Klammerpaaren stehen. Die eigentliche Formel ist mir getrost ziemlich egal, die Berechnung macht ein anderes Program.
    Man kann alles schaffen. Man muss es nur wollen ;)
    www.regetskcob.github.io
  • Fortrackz schrieb:

    Könnte man dies nicht auch mit Regex lösen? Wäre sicherlich dann noch weniger Zeilen Code

    Ich würde sagen, nein. Selbst, wenn du einen Regulären Ausdruck hin bekommst, der beliebig verschachtelte öffnende und schließende Klammern korrekt erkennt und heraus findet, ob ein '+' nicht eingeklammert ist, wäre der bestimmt deutlich länger, als jeder Code.
  • zerm schrieb:

    ch würd sagen, dass das nicht kontext-frei ist, und daher RegEx nicht funktionieren?

    Hä? Arithmetische Ausdrücke sind doch in der Regel Typ-2-Sprachen und damit kontextfrei (aber natürlich keine Typ-3-Sprachen). Oder verstehe ich da was falsch? Reguläre Ausdrücke sind in jedem Fall das falsche Mittel.
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Hä? Arithmetische Ausdrücke sind doch in der Regel Typ-2-Sprachen und damit kontextfrei (aber natürlich keine Typ-3-Sprachen). Oder verstehe ich da was falsch? Reguläre Ausdrücke sind in jedem Fall das falsche Mittel.

    Bin mir ja auch nicht mehr sicher (heh, wie auch Amin) -- dachte wegen den Klammern, weil es eben darauf ankommt, wieviele offene Klammern du vorher hattest. Und das passt eben nicht (?).
    C++
  • zerm schrieb:

    Bin mir ja auch nicht mehr sicher (heh, wie auch Amin) -- dachte wegen den Klammern, weil es eben darauf ankommt, wieviele offene Klammern du vorher hattest. Und das passt eben nicht (?).

    Ja, und das kannst Du ja mit einem Kellerautomaten abfrühstücken, also Typ-2 bzw. kontextfrei. Für kontextsensitive (= nicht kontextfreie) Grammatiken brauchst Du ja schon ein Turingmaschinchen.
    „Meine Komplikation hatte eine Komplikation.“