none
String mit zwei Punkten korrekt zählen RRS feed

  • Frage

  • Hallo Leute,

    meiner Methode wird ein String übergeben, deren einzelne Zeichen wic folgt gezählt werden:

                   foreach(char sign in file) {
                        /*zählt nur die Zeichen von ASCII_hex(20) bis ASCII_hex(7E)
                         20(hexaedezimal)=32(dezimal) / 7E(hexadezimal)=126(dezimal)
                         ZZgl. werden dt. Umlaute(ä,ö,ü,Ä,Ö,Ü,ß) mitgezählt
                         */
                        if(((int) sign == 10) || ((int) sign >= 32 && (int) sign <= 126) || this.UmlauteMitzaehlen(sign, leave))
                                countSigns++;
                    }

    Wenn in dem String allerdings zwei aufeinanderfolgende Punkte beinhaltet sind, soll er diese zwei Punkte(int(sign)==46) als nur ein Zeichen zählen.

    Wie codiere ich das am günstigsten, ohne eine zusätzliche Zählvariable bzw. eine zählerindizierte Schleife zu verwenden ? Folgenden Ansatz habe ich bisher

          if((int) sign == 46) { 
                            //wie geht's hier weiter ??
                            }





    • Bearbeitet tklustig Mittwoch, 16. Januar 2019 10:24
    Mittwoch, 16. Januar 2019 10:19

Antworten

  • Den Originalstring in einen anderen zu kopieren, zwei Punkte mit einem zu ersetzten, zu zählen ist mir zu aufwendig...

    Echt jetzt?

    String x = <OriginalString>.Replace( "..", "." );

    ist dir zu aufwändig?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    • Als Antwort markiert tklustig Mittwoch, 16. Januar 2019 11:04
    • Tag als Antwort aufgehoben tklustig Mittwoch, 16. Januar 2019 18:12
    • Als Antwort markiert tklustig Freitag, 18. Januar 2019 14:39
    Mittwoch, 16. Januar 2019 10:37
    Moderator

Alle Antworten

  • Hi,

    ich würde einfach mehrfache bzw. in deinem Fall doppelte Punkte durch einen Punkt ersetzen.

    deinString = deinString.Replace( "..", "." );

    Natürlich nicht im Originalstring, sondern nur in der Variante, die für die Zählung dient.

    Wenn Du allerdings auch ... und ...., usw. nur einmal zählen willst, musst Du die Ersetzung ggfs. mehrfach durchführen oder Regex verwenden. Mit letzterem könntest Du auch einfach alles entfernen, was nicht in deinem Zählbereich vorkommt und von dem, was übrigbleibt, die Länge per <String>.Length ermitteln.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Mittwoch, 16. Januar 2019 10:26
    Moderator
  • Der String selber darf an dieser Stelle nicht verändert werden. Zumindest der Originalstring nicht. Den Originalstring in einen anderen zu kopieren, zwei Punkte mit einem zu ersetzten, zu zählen ist mir zu aufwendig...
    Mittwoch, 16. Januar 2019 10:34
  • Den Originalstring in einen anderen zu kopieren, zwei Punkte mit einem zu ersetzten, zu zählen ist mir zu aufwendig...

    Echt jetzt?

    String x = <OriginalString>.Replace( "..", "." );

    ist dir zu aufwändig?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    • Als Antwort markiert tklustig Mittwoch, 16. Januar 2019 11:04
    • Tag als Antwort aufgehoben tklustig Mittwoch, 16. Januar 2019 18:12
    • Als Antwort markiert tklustig Freitag, 18. Januar 2019 14:39
    Mittwoch, 16. Januar 2019 10:37
    Moderator
  • Nö, eigentlich nicht. Von der Logik her ist das wohl am aller schnellsten:

                  string String2BeCounted = String.Empty;
                    String2BeCounted = file.Replace("..", ".");
                    foreach(char sign in String2BeCounted) {
                        /*zählt nur die Zeichen von ASCII_hex(20) bis ASCII_hex(7E)
                         20(hexaedezimal)=32(dezimal) / 7E(hexadezimal)=126(dezimal)
                         ZZgl. werden dt. Umlaute(ä,ö,ü,Ä,Ö,Ü,ß) mitgezählt
                         */
                        if(((int) sign == 10) || ((int) sign >= 32 && (int) sign <= 126) || this.UmlauteMitzaehlen(sign, leave))
                                countSigns++;
                    }

    Mittwoch, 16. Januar 2019 10:49
  • Lösung bietet sich doch nicht an, da in einem zweiten Zählvorgang die doppelten Punkte wieder mitgezählt werden müssen. Ich könnte der Methode ein Boolean übergeben, und davon abhängig die Replace-Methode ausführen, oder eben nicht. Dazu müsste ich allerdings jede aufrufende Stellen verändern, und es sind derer sehr viele. Ginge das nicht eleganter? Monmetan habe ich das so codiert, elegant geht jedoch anderst. Könnte man für dieses Problem nicht einen LINQ Ausdruck verwenden?

            public int zeichenZaehlen(string file, bool leave, bool subtract)
            {
                int countSigns = 0;
                try {
                    if (subtract) {
                        string String2BeCounted = String.Empty;
                        String2BeCounted = file.Replace("..", ".");
                        foreach (char sign in String2BeCounted) {
                            /*zählt nur die Zeichen von ASCII_hex(20) bis ASCII_hex(7E)
                             20(hexaedezimal)=32(dezimal) / 7E(hexadezimal)=126(dezimal)
                             ZZgl. werden dt. Umlaute(ä,ö,ü,Ä,Ö,Ü,ß) mitgezählt
                             */
                            if (((int)sign == 10) || ((int)sign >= 32 && (int)sign <= 126) || this.UmlauteMitzaehlen(sign, leave))
                                countSigns++;
                        }
                    }
                    else {
                        foreach (char sign in file) {
                            if (((int)sign == 10) || ((int)sign >= 32 && (int)sign <= 126) || this.UmlauteMitzaehlen(sign, leave))
                                countSigns++;
                        }
                    }
                }
                catch (Exception error) {
                    _logger.Error("Error in zeichenZaehlen() detected" + Environment.NewLine + error.ToString());
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("Error in zeichenZaehlen() detected, which has been protocollated in log");
                    Console.ForegroundColor = ConsoleColor.Green;
                    if (leave) {
                        _logger.Warn("Based on Boolean parameter given as {0}, an unaceptable error has occured - program exited!", leave);
                        Console.ForegroundColor = ConsoleColor.Yellow;
                        Environment.Exit(32);
                    }
                }
                return countSigns;
            }





    • Bearbeitet tklustig Mittwoch, 16. Januar 2019 18:26
    Mittwoch, 16. Januar 2019 18:21
  • Hi,
    natürlich geht das auch mit LinQ. 

          public int zeichenZaehlen(string file, bool leave, bool subtract)
          {
            try
            {
              return (from c in (subtract)? file: file.Replace("..", ".")
                      where ((int)c == 10) || ((int)c >= 32 && (int)c <= 126)
                      || this.UmlauteMitzaehlen(sign, leave)
                      select c).Count();
            }
            catch (Exception error)
            {
              Console.WriteLine(error.ToString());
            }
            return -1;
          }


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP für Developer Technologies)
    Meine Homepage mit Tipps und Tricks

    Mittwoch, 16. Januar 2019 19:05