Fraggla Geschrieben 3. September 2010 Geschrieben 3. September 2010 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... Zitieren
Klotzkopp Geschrieben 3. September 2010 Geschrieben 3. September 2010 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. Zitieren
Pointerman Geschrieben 3. September 2010 Geschrieben 3. September 2010 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 Zitieren
Fraggla Geschrieben 3. September 2010 Autor Geschrieben 3. September 2010 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. Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 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 Zitieren
Fraggla Geschrieben 3. September 2010 Autor Geschrieben 3. September 2010 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? Zitieren
Klotzkopp Geschrieben 3. September 2010 Geschrieben 3. September 2010 Wirf das raus: char VTR1 = VTR[0]; char VTR2 = VTR[1]; char VTR3 = VTR[2]; char VTR4 = VTR[3]; char VTR5 = VTR[4];[/code]Die Variablen benutzt du nicht. Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 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 Zitieren
Fraggla Geschrieben 3. September 2010 Autor Geschrieben 3. September 2010 Der Vorschlag ist nicht schlecht, jedoch ist der ausgegebene Text dann nicht mehr Rechtsbündig, da die 0len am Anfang gelöscht und nicht durch blanks ersetzt werden. Zitieren
it_crowd Geschrieben 3. September 2010 Geschrieben 3. September 2010 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 Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 Der Vorschlag ist nicht schlecht, jedoch ist der ausgegebene Text dann nicht mehr Rechtsbündig, da die 0len am Anfang gelöscht und nicht durch blanks ersetzt werden. string bietet die Methoden PadLeft() und PadRight() an. String.PadLeft-Methode (Int32, Char) (System) Zitieren
it_crowd Geschrieben 3. September 2010 Geschrieben 3. September 2010 for (int i = 0; i < zahl.Length; i++) { if (zahl[i] == '0' && !break_if) { zahl_array[i] = ' '; } else { zahl_array[i] = zahl[i]; break_if = true; } } das wäre dann mein vorschlag Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 (bearbeitet) Alles viel zu lang. Für die Ausgabe reicht eine Zeile (wenn etwas unübersichtlich und ohne Fehlerbehandlung). Bearbeitet 3. September 2010 von lbm1305 Zitieren
it_crowd Geschrieben 3. September 2010 Geschrieben 3. September 2010 geht es nur um die ausgabe? ich dacht er muss es in ein char-array speichern Zitieren
Fraggla Geschrieben 3. September 2010 Autor Geschrieben 3. September 2010 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 Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 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... Zitieren
_n4p_ Geschrieben 3. September 2010 Geschrieben 3. September 2010 ähm, etwa so result.ToString().PadLeft(5, ' '); ach mist, 2te seite übersehen .. sry Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 (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 3. September 2010 von lbm1305 Zitieren
_n4p_ Geschrieben 3. September 2010 Geschrieben 3. September 2010 das is doch drin, zumindest hatte ich eins reingeschrieben. die anzahl dynamisch ermitteln wäre sicher gut, aber er hatte die 5 ja schon drin wollte es nur zusammensetzen =) Zitieren
NerdonRails Geschrieben 3. September 2010 Geschrieben 3. September 2010 (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 3. September 2010 von NerdonRails Refactoring Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 Uuii...gleich als Extension-Method. Nicht das der Threadersteller damit überfordert ist ?! Zitieren
NerdonRails Geschrieben 3. September 2010 Geschrieben 3. September 2010 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. Zitieren
NerdonRails Geschrieben 3. September 2010 Geschrieben 3. September 2010 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. Zitieren
lbm1305 Geschrieben 3. September 2010 Geschrieben 3. September 2010 Jetzt raucht die Birne (nicht bei mir) :-) Aber was soll das Interface ICountingProcessor? Dann kann ich gleich IProcessor<T> implementieren. Zitieren
NerdonRails Geschrieben 3. September 2010 Geschrieben 3. September 2010 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. Zitieren
Empfohlene Beiträge
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.