Zum Inhalt springen

[C#] Verständnis Problem mit Arrays


Empfohlene Beiträge

Geschrieben

Hi,

ich hab ne Knobelaufgabe im Betrieb bekommen und brüte jetzt seit mehreren Stunden drüber.

Die Aufgabe ist, eine 5stellige Zahl einzulesen, vorgestellte Nullen zu entfernen, aber normale 0 in Zahlen zu lassen.

Sprich

aus 00010 mach 10

aus 00107 mach 107

usw.

Der Lösungsweg ist mir eigentlich schon klar, aber die Syntax krieg ich irgendwie nicht hin.

Hatte bisher ~ 100 verschiedene Ansätze wie ich an das Ding ran bin, kriegs aber einfach nicht hin.

Hier mein bisheriger Code:

static void Main(string[] args)

        {

            System.Console.WriteLine("Geben Sie die Vertreternummer ein");

            string Vertreternummer = Console.ReadLine();

            //char mychar =  Vertreternummer[0];

            char[] myChar = Vertreternummer.ToCharArray();

            int c = 0;

            char i = '0';

            int b = c;


            for (c = 0 ; c <= 4; c++)

                if (myChar[c] == i)

                {

                    Console.Write(" ");

                }

                else

                {

                    for (b = c; c <= 4; c++)

                        if (myChar[c] > i)

                            Console.Write(myChar[c]); 

                        break;



                }

Es ist mit Sichereit ein seltsames Konstrukt, vorallem mit dem i , c und b.

Die sind dank try + error stehen geblieben...

WICHTIG: Es wäre schön, wenn ihr nicht einfach die Lösung posten würdet, sondern mir vielmehr mit der Syntax helfen könnt bzw. ggf auch Denkfehler hinweisen könnt.

Mfg

Fraggla

P.S: Bei der Häufigkeit wie ich hier Fragen stell, sollt ich mal n Kasten Bier besorgen...

Geschrieben
Der Lösungsweg ist mir eigentlich schon klar, aber die Syntax krieg ich irgendwie nicht hin.
Beschreib doch mal deinen Lösungsweg auf Deutsch. Aus dem Code ist der nicht so gut ersichtlich.

Ich würde einfach den eingegebenen Text in eine Zahl umwandeln, und die wieder in Text.

Geschrieben

Moin!

Hast Du denn als Auflage bekommen, das Array selbst durchzugrasen?

Ansonsten hier mein Vorschlag:

-prüfe ob die Stringgröße >0 && <6 ist.

-wandle den String mit int.tryparse(deinString) in einen int und prüfe dabei gleichzeitig, ob es ein gültiger Integer ist

-gib den Int aus

-freu Dich, weil Du fertig bist ;)

Geschrieben

String wird eingegeben und soll in ein char array umgewandelt werden

for schleife überprüft array von vorne durch. Wird eine 0 eingelesen, kommt ein Blank rein, da der Text später rechtsbündig sein soll:

for (c = 0 ; c <= 4; c++)

                if (myChar[c] == i)

                {

                    Console.Write(" ");

                }

wird eine andere Zahl als 0 eingelesen, soll der rest des Arrays ausgegeben werden. Die Schleife soll dann jede weitere 0 normal behandeln:

for (b = c; c <= 4; c++)

                        if (myChar[c] > i)

                            Console.Write(myChar[c]); 

                        break;

Danke für die schnelle Antwort.

Geschrieben
String wird eingegeben und soll in ein char array umgewandelt werden

In Deinem ersten Post steht aber nichts von "soll in ein Char-Array" umgewandelt werden.

Die Antwort für Dein Problem findest Du in den darauf folgenden Antworten.

Ansonsten ist ein String ein Char-Array


string a = "Hallo Welt";

char a1 = a[0]; // H

char a2 = a[1]; // a

Geschrieben

Danke IBM. Das war der Denkfehler.

Meine Lösung:

Console.WriteLine("Geben Sie die Vertreternummer ein: ");

string VTR = Console.ReadLine();

char VTR1 = VTR[0];

char VTR2 = VTR[1];

char VTR3 = VTR[2];

char VTR4 = VTR[3];

char VTR5 = VTR[4];

int c1 = 0 ;

int c2 = c1;

if (VTR == "00000" )

{

Console.WriteLine("Ungültige Eingabe");

}

else

{

for (c1 = 0; c1 <= 4; c1++)

if (VTR[c1] == '0')

{

Console.Write(" ");

}

else

{

for (c2 = c1; c2 <= 4; c2++)

if (VTR[c2] > 0)

Console.Write(VTR[c2]);

break;

}

}

Console.ReadLine();

Vorschläge zur Verbesserung?

Geschrieben

Vorschläge zur Verbesserung?

Musst Du ein Char-Array benutzen?

Denn der Code ist für das Ergebnis viel zu lang.

Anlehnend an den Code von Klotzkopp:


string value = "00170";

int result = int.Parse(value); // 170

// Besser wäre hier vielleicht die TryParse() Methode.

..

Console.WriteLine(result.ToString()); // 170

Geschrieben

Hi fraggla,

du gehst einfach den string wie ein array in einer Schleife durch so wie von ibm1305 beschrieben

wenn du ne null stehen hast schreibst n blank in dein ausgabe-array rein sobald am geprüften index keine null steht biste ja schon fertig

dann musst du nur noch überlegen wie du die restlichen werte in dein array reinkopierst. ;)

ich hab auch nen fertigen code dafür, falls du nicht drauf kommen sollst, aber überleg erst mal selber, so lernst das am besten

lg

it_crowd

Geschrieben
Da ich das noch nie gemacht habe, wäre es schön wennd u mir n Beispiel liefern könntest, wie ich result.ToString() mit str.PadLeft (5, x) verbinden kann

Siehe mein Link zur MSDN unter Beispiele ;-)


result.ToString().Pad...

Geschrieben (bearbeitet)
ähm, etwa so

result.ToString().PadLeft(5, ' ');

ach mist, 2te seite übersehen .. sry

Die Anzahl der Stellen würde ich aus dem String ermitteln.

Ansonsten müsste noch in die beiden Hochkommas ein Leerzeichen rein.

EDIT: Problem bei dieser Variante: Das Programm stürzt, wenn keine Fehlerbehandlung vorhanden, bei einer Eingabe eines Zeichens oder Buchstaben ab.

Daher wäre die TryParse() Methode besser geeignet.

Bearbeitet von lbm1305
Geschrieben (bearbeitet)

Hier ein Lösungsansatz:


public static class StringExtensions

    {

        public static String ReplaceFromStartUntil(this String current, Char charToReplace, Char replaceWith)

        {                       

            return current.Substring(current.GetCharCountUntilOtherCharAppears(charToReplace)).PadLeft(current.Length, replaceWith);

        }


        public static String RemoveFirstOccurencesOf(this String current, Char charToRemove)

        {             

            return current.Substring(current.GetCharCountUntilOtherCharAppears(charToRemove));

        }


        private static Int32 GetCharCountUntilOtherCharAppears(this String current, Char charToCount)

        {

            Int32 index = 0;

            Char currentChar = current[index];

            while (currentChar == charToCount)

            {

                index++;

                currentChar = current[index];

            }

            return index;

        }

    }

Und hier die Tests die belegen das das ganze auch fuppt:

[TestClass]

    public class UnitTest1

    {

        [TestMethod]

        public void TestThatStartingZerosAreReplacedWithCustomCharacter()

        {

            String actual = "00107";

            String expected = "  107";

            Assert.IsTrue(actual.ReplaceFromStartUntil('0', ' ') == expected);


            actual = "00010";

            expected = "   10";

            Assert.IsTrue(actual.ReplaceFromStartUntil('0', ' ') == expected);

        }


        [TestMethod]

        public void TestThatAStringWithoutOccurencesIsNotModified()

        {

            String actual = "12345";

            String expected = "12345";


            Assert.IsTrue(actual.ReplaceFromStartUntil('0', ' ') == expected);

        }


[TestMethod]

        public void TestThatTheFirstOccurencesOfACharAreRemovedFromAString()

        {

            String actual = "000107";

            String expected = "107";


            Assert.IsTrue(actual.RemoveFirstOccurencesOf('0') == expected);

        }

    }

Bearbeitet von NerdonRails
Refactoring
Geschrieben
Uuii...gleich als Extension-Method. Nicht das der Threadersteller damit überfordert ist ?!

Naja, ist am elegantesten wenn man nicht gleich wieder eine komplette Objekthierarchie aufbauen möchte.

Und sooo viel Voodoo sind Extension-Methods nun auch wieder nicht.

Geschrieben
Uuii...gleich als Extension-Method. Nicht das der Threadersteller damit überfordert ist ?!

Hier noch ein etwas anderer Ansatz:


public interface IProcessor<ResultType>

    {        

        ResultType Process(String current, Char charToProcess);

    }


public interface ICountingProcessor : IProcessor<Int32>

    {

    }


public class CountingProcessor : ICountingProcessor

    {

        public Int32 Process(String current, Char charToProcess)

        {

            Int32 index = 0;

            Char currentChar = current[index];

            while (currentChar == charToProcess)

            {

                index++;

                currentChar = current[index];

            }

            return index;

        }

    }


public interface IStringProcessor

    {

        String ReplaceFromStartUntil(Char charToReplace, Char replaceWith);

        String RemoveFirstOccurencesOf(Char charToRemove);

    }


public class StringProcessor : IStringProcessor

    {

        // Properties

        private String StringToProcess

        {

            get;

            set;

        }


        private ICountingProcessor CountingProcessor

        {

            get;

            set;

        }


        // Constructors

        public StringProcessor(String stringToProcess)

        {

            this.StringToProcess = stringToProcess;

            this.CountingProcessor = new CountingProcessor();

        }


        // Methods

        public String ReplaceFromStartUntil(Char charToReplace, Char replaceWith)

        {            

            Int32 numberOfCharsToSnip = this.CountingProcessor.Process(this.StringToProcess, charToReplace);

            return this.StringToProcess.Substring(numberOfCharsToSnip).PadLeft(this.StringToProcess.Length, replaceWith);

        }


        public string RemoveFirstOccurencesOf(Char charToRemove)

        {

            Int32 numberOfCharsToSnip = this.CountingProcessor.Process(this.StringToProcess, charToRemove);

            return this.StringToProcess.Substring(numberOfCharsToSnip);

        }

    }

Und natürlich Tests die das ganz belegen:

[TestMethod]

        public void TestThatACountingProcessorCountsTheAppearancesOfACharacterUntilAnotherCharacterApears()

        {

            String dummyData = "000107";

            Int32 expected = 3;

            Int32 actual;

            IProcessor<Int32> countingProcessor = new CountingProcessor();

            actual = countingProcessor.Process(dummyData, '0');

            Assert.IsTrue(actual == expected);

        }


        [TestMethod]

        public void TestThatStartingZerosAreReplacedWithCustomCharacterByAStringProcessor()

        {            

            String actual = "00107";

            String expected = "  107";


            IStringProcessor processor = new StringProcessor(actual);

            Assert.IsTrue(processor.ReplaceFromStartUntil('0', ' ') == expected);


            actual = "00010";

            processor = new StringProcessor(actual);

            expected = "   10";

            Assert.IsTrue(actual.ReplaceFromStartUntil('0', ' ') == expected);

        }


        [TestMethod]

        public void TestThatAStringWithoutOccurencesIsNotModifiedByAStringProcessor()

        {

            String actual = "12345";

            String expected = "12345";

            IStringProcessor processor = new StringProcessor(actual);


            Assert.IsTrue(processor.ReplaceFromStartUntil('0', ' ') == expected);

        }


        [TestMethod]

        public void TestThatTheFirstOccurencesOfACharAreRemovedFromAStringByAStringProcessor()

        {

            String actual = "000107";

            String expected = "107";

            IStringProcessor processor = new StringProcessor(actual);

            Assert.IsTrue(processor.RemoveFirstOccurencesOf('0') == expected);

        }

Das dürfte ein recht sauberer Ansatz sein, der auch recht erweiterbar ist.

Geschrieben
Jetzt raucht die Birne (nicht bei mir) :-)

Aber was soll das Interface ICountingProcessor?

Dann kann ich gleich IProcessor<T> implementieren.

Nur eine Angewohnheit, alles so präzise zu benennen wie möglich.

IProcessor könnte auch noch von anderen Klassen implementiert werden, wodurch beim lesen des Codes evtl. nicht mehr der eigentliche Sinn heraus kommt. Ihr wisst schon was ich meine. Ausserdem könnte man in ICountingProcessor noch weitere, spezifische Methoden-Signaturen definieren die in IProcessor nichts zu suchen hätten.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

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...