Zum Inhalt springen

Wörter aus String in ArrayList


Empfohlene Beiträge

Geschrieben

Hallo,

ich lerne seit einigen Wochen C# und habe versucht eine Methode zu programmieren, mit der ich einen String aus dem Parameter, so zerlegen kann, dass die einzelnen Wörter ohne .,!,?,Zeilenumbrüche, usw. in einer ArrayList zurückgegeben werden.

Bin aber leider an eine Schwelle meiner Ideen gekommen und hab mich nach einer Stunde verzweifelten Denkens, dazu entschieden ein paar Fachleute zu fragen.

Wär echt toll wenn mir wer helfen könnte.

Mein Code:

public ArrayList WoerterEinlesen(String text)

        {

            Char[] trimArr = new Char[5]{' ', '!', '.', '?', '\n'}; 

            ArrayList words = new ArrayList();

            int pos = 0;

            int signs = 0;


            // D A S   I S T   E I N   B E I S P I E L

            // 0 1 2 3 4 5 6 7 8 9


            // Solange die Startposition nicht das Ende des Textes erreicht

            while (pos + signs < text.Length)

            {

                // wird die Anzahl der Zeichen bis zum nächsten Leerzeichen in signs gespeichert

                signs = text.IndexOf(" ", pos);


                if (signs < 1)

                    signs = text.IndexOf(".", pos);

                if (signs < 1)

                    signs = text.IndexOf("!", pos);

                if (signs < 1)

                    signs = text.IndexOf("?", pos);


                // wenn signs 0 ist braucht man nichts zu tun

                if (signs > 0)

                {

                    // ein neues CharArray, mit so vielen Plätzen 

                    // wie unser Wort lang ist wird erstellt

                    Char[] chrArr = new Char[signs];


                    // Solange die Zählervariable i nicht die Länge des Wortes erreicht

                    for (int i = 0; i < signs; i++)

                    {

                        // schreibe den Text in das CharArray

                        chrArr[i] = text[pos + i];  // IndexOutOfRange Exeption...


                    }


                    // Anschließend wird aus dem CharArray ein String und der wird words(ArrayList)

                    // angefügt

                    words.Add(new String(chrArr).Trim(trimArr));

                }

                pos = signs + 1;

            }


            return words;

        }

Gruß Conny

Geschrieben (bearbeitet)

Hi Conny,

bin in C# auch kein Fachmann (habe auch erst vor einigen Monaten damit angefangen:cool:), aber hier mal zwei Alternativen.

1. Alternative



    private ArrayList getElementsFromString(String sText)

    {

        // diese Variante ersetzt die angegebenen Sonderzeichen durch Leerzeichen

        // und nutzt Split bei Leerzeichen um eine ArrayList zu erzeugen

        ArrayList aList = new ArrayList();

        Char[] aReplace = new Char[] { '.', ',', '!', '?', ':', ';' };

        foreach (Char c in aReplace)

        {

            sText = sText.Replace(c, ' ');

        }

        sText = sText.Trim();

        // prüfen ob sText nach Trim der Leerzeichen am Anfang und/oder Ende

        // überhaupt einen Inhalt hat

        if (sText != "")

        {

            // hier werden nun doppelte Leerzeichen durch ein einfaches Leerzeichen ersetzt

            while (sText.Contains("  "))

            {

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

            }

            // nun wird per Split der String an Leerzeichen geteilt

            // und jeder der gesplitteten Inhalte zur ArrayList als einzelne Werte hinzugefügt

            aList.AddRange(sText.Split(' '));

        }

        return aList;

    }

2. Alternative

    private ArrayList getElementsFromString2(String sText)

    {

        // Diese Variante prüft jedes Zeichen und "baut" die einzelnen "Elemente" zusammen

        ArrayList aList = new ArrayList();

        sText = sText.Trim();

        if (sText != "")

        {

            String sElement = "";

            // jedes Zeichen überprüfen, ob es ein

            // Buchstabe (ASCII-Wert zwischen 65 und 91, sowie 97 und 122) ist

            // (kann um weitere, erwünschte Werte z.B. Ziffern, Sonderzeichen usw. erweitert werden)

            for (int i = 0; i < sText.Length; i++)

            {

                // Char aus String holen

                Char cCompare = sText[i];

                // Wert des Chars ermitteln

                int iValue = System.Convert.ToInt32(cCompare);

                // Vergleichen, ob Wert innerhalb des gewünschten Bereiches liegt

                if ((iValue > 64 && iValue < 92) || (iValue > 96 && iValue < 123))

                {

                    // ist eines der erlaubten Zeichen - zu sElement hinzufügen

                    sElement += sText[i];

                }

                else

                {

                    // ist kein erlaubtes Zeichen

                    // prüfen ob nicht am Anfang und sElement nicht leer ist

                    if (i > 0 && sElement != "")

                    {

                        // aktuelles Zeichen ist kein erlaubtes Zeichen

                        // letztes sElement zur ArrayList hinzufügen

                        aList.Add(sElement);

                        // sElement zurücksetzen für nächsten Durchlauf

                        sElement = "";

                    }

                }

            }

        }

        return aList;

    }

Dein Problem kommt davon, das du bei

chrArr = text[pos + i];

über das Ende des Textes hinaus versuchst, auf den String zuzugreifen (irgendwann ist text[pos + i] hinter dem Ende des Textes).

Ich hoffe, dass hat dir weitergehholfen.

MFG

DerDa71

Bearbeitet von DerDa71
Geschrieben

Hi,

ich hatte in der 2. Variante noch einen Fehler bzw. etwas vergessen...


    private ArrayList getElementsFromString2(String sText)

    {

        // Diese Variante prüft jedes Zeichen und "baut" die einzelnen "Elemente" zusammen

        ArrayList aList = new ArrayList();

        sText = sText.Trim();

        if (sText != "")

        {

            String sElement = "";

            // jedes Zeichen überprüfen, ob es ein

            // Buchstabe (ASCII-Wert zwischen 65 und 91, sowie 97 und 122) ist

            // (kann um weitere, erwünschte Werte z.B. Ziffern, Sonderzeichen usw. erweitert werden)

            for (int i = 0; i < sText.Length; i++)

            {

                // Char aus String holen

                Char cCompare = sText[i];

                // Wert des Chars ermitteln

                int iValue = System.Convert.ToInt32(cCompare);

                // Vergleichen, ob Wert innerhalb des gewünschten Bereiches liegt

                if ((iValue > 64 && iValue < 92) || (iValue > 96 && iValue < 123))

                {

                    // ist eines der erlaubten Zeichen - zu sElement hinzufügen

                    sElement += sText[i];

                }

                else

                {

                    // ist kein erlaubtes Zeichen

                    // prüfen ob nicht am Anfang und sElement nicht leer ist

                    if (i > 0 && sElement != "")

                    {

                        // aktuelles Zeichen ist kein erlaubtes Zeichen

                        // letztes sElement zur ArrayList hinzufügen

                        aList.Add(sElement);

                        // sElement zurücksetzen für nächsten Durchlauf

                        sElement = "";

                    }

                }

            }

            // Falls am Ende ein (oder mehrere) erlaubte(s) Zeichen war(en),

            // muss noch das letzte Element zur ArrayList hinzugefügt werden

            if (sElement != "")

            {

                 // letztes sElement zur ArrayList hinzufügen

                 aList.Add(sElement);

             }

        }

        return aList;

    }

MFG

DerDa71

Geschrieben

Joa, rießen dank!! Hab die Methode gleich in meinem Programm verbaut(Des nebenbei zählen soll wie oft jedes Wort in einem Text vorkommt...). Funktioniert super.

Danke....

Gruß Conny

Geschrieben

Moin,

anstatt einer ArrayList würde ich eine Generische Liste (List<T>) verwenden, wenn es sich um den gleichen Datentyp handelt, den den Liste verwalten soll. Bei einer ArrayList müsste man noch Casten.

Geschrieben

a) wie bereits gesagt sollten statt ArrayList generische Listen verwendet werden.

Ansonsten lässt sich das ganze auch als Dreizeiler ausdrücken:

public List<string> Split(string input)

{

    var ignoredChars = new[] {"!", ".", ",", "?", "\n"};

    var words = input.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);

    return words.Where(x => !ignoredChars.Contains(x)).ToList();

}

Die String.Split Methode kann selbstständig leere Einträge herausfischen und die Where Methode sammelt dann alles auf, was nicht einem der ignorierten Chars entspricht. Falls es unbedingt ne Array List sein _muss_ kann man das Ergebnis der Methode auch in ne ArrayList stecken - return new ArrayList(words.Where(...));

Geschrieben

nochmal danke..

ich hab aber immer noch nicht ganz den Vorteil von generischen Listen gegenüber einer ArrayList verstanden.:confused:

Ich glaub ich muss nochmal die LINQ-Abragen:upps wiederholen. Naja wennigstens kann ich jetzt ruhig weiterprogrammieren.:D

Gruß Conny

Geschrieben

ich hab aber immer noch nicht ganz den Vorteil von generischen Listen gegenüber einer ArrayList verstanden.:confused:

Eine ArrayList nimmt alle Elemete auf, die vom Typ "Object" sind oder abgeleitet wurden (string, int aber auch eigene Datentypen). Das ist aber auch schon der Vorteil. Zum Auslesen musste Du zur Laufzeit den eigentlichen Datentyp bestimmten und in diesen Casten.

Eine generische Liste kann nur den angegebenen Datentyp aufnehmen. (List<string>, List<int>, List<Person>. Damit entfällt das Casten beim auslesen und es können nur diese Datentypen aufgenommen werden.

Es spart ein wenig Zeit, wenn man nicht casten muss. :-)

Geschrieben

Wichtiger ist, dass generische Listen Typensicher sind und damit der Compiler mehr Fehler abfangen kann. In eine Array Liste kannste alles reinschmeißen und es knallt dann ggf. beim Casten zur Laufzeit. Das passiert dir mit ner generischen Liste nicht.

Geschrieben

Boah ey.... programmieren ist echt nur ein Gehangle von Problem zu Problem...

Ich glaub ich mir doch als erste Programmierpraxis ein Tick zu schwieriges Beispiel ausgesucht...

Naja, ich beschreib mal mein Problem:

Die Methode faerben(int index, Color currentColor) soll aus einer Listbox(lstAusgabe) an der Position index einen String auslesen. Die Liste schaut ungefähr so aus:

64 die

39 der

20 ist

12 man

9 er

...

Nun muss ich logischerweise den String spliten und dann trimen. Von dem zurückgegebenen Array das letzte Element sollte das Wort beinhalten, welches ich im Text(der in txtHauptfeld(RichTextBox) steht) färben will(mit currentColor).

Ich habe geschrieben:

public void faerben(int index, Color currentColor)

        {

            // Erst alles wieder normal machen

            txtHauptfeld.SelectAll();

            txtHauptfeld.SelectionBackColor = Color.White;


            int pos = 0;

            int suc = 0;


            if (index < words.Count)

            {

                String temp = Convert.ToString(lstAusgabe.Items[index]);

                String[] tempSplit = temp.Split(' ');


                int WordsToColor = Convert.ToInt32(tempSplit[0]);

                String WordToColor = tempSplit[tempSplit.Length - 1].Trim();

                Boolean frontIsLetter = false;


                while (suc < WordsToColor)

                {

                    int selectStart = txtHauptfeld.Text.IndexOf(WordToColor, pos);


                    if (selectStart > 0 && selectStart < txtHauptfeld.Text.Length)

                    {

                        try

                        {

                            txtHauptfeld.Select(selectStart, WordToColor.Length); // ArgumentOutOfRangeException


                            if (selectStart != 0)

                            {

                                int frontValue = Convert.ToInt32(txtHauptfeld.Text[selectStart - 1]);


                                if ((frontValue > 64 && frontValue < 92) || (frontValue > 96 && frontValue < 123) || frontValue == 246 || frontValue == 228 || frontValue == 252 || frontValue == 220 || frontValue == 214 || frontValue == 196)

                                    frontIsLetter = true;

                            }



                            int backValue = Convert.ToInt32(txtHauptfeld.Text[selectStart + txtHauptfeld.SelectedText.Length]);


                            if (!((backValue > 64 && backValue < 92) || frontIsLetter || (backValue > 96 && backValue < 123) || backValue == 246 || backValue == 228 || backValue == 252 || backValue == 220 || backValue == 214 || backValue == 196))

                            {

                                txtHauptfeld.SelectionBackColor = currentColor;


                                pos = selectStart + txtHauptfeld.SelectionLength;


                                suc++;

                            }

                            else

                                pos = selectStart + txtHauptfeld.SelectionLength;

                        }

                        catch (Exception e)

                        {

                            MessageBox.Show(e.Message);

                        }

                    }

                    else

                        pos = selectStart + txtHauptfeld.SelectionLength;

                }

            }

        }
Ich schätze ich programmiere noch deutlich zu kompliziert... Ich bekomme nun bei dieser Codezeile,
txtHauptfeld.Select(selectStart, WordToColor.Length);
eine ArgumentOutOfRangeException. Dabei habe ich keinen Schimmer wie es dazu kommt. Die Methode wird ausschließlich durch das SelectedIndexChange von der lstAusgabe aufgerufen:
        private void lstAusgabe_SelectedIndexChanged(object sender, EventArgs e)

        {

            if (lstAusgabe.SelectedIndex != 0)

                if (farbig)

                    faerben(lstAusgabe.SelectedIndex, Color.Red);

        }

wär echt schön wenn mir da noch wer helfen könnte, dann könnte ich zumindest mein erstes Projekt abschließen.:D

Gruß Conny

Gast
Dieses Thema wurde nun für weitere Antworten gesperrt.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...