# Buchstaben zwischen zwei Indizes entfernen



## Kirby.exe (29. Nov 2019)

Also wir haben die Aufgaben eine Methode zu schreiben die aus einem String alle Buchstaben entfernt die zwischen den eingelesenen Indizes liegen, die Frage die ich mir Stelle ist, wie setze ich das um, ich habe eine Methode geschrieben die es schafft einen Buchstaben an einem bestimmten Index zu löschen:


```
String result = "";
        for (int i = 0; i <s.length(); i++)
          {
            if(s.charAt(i) == s.charAt(a)) {
                continue;
            }else {
                result += s.charAt(i);
            }
           
          }
        return result;
```


----------



## kneitzel (29. Nov 2019)

Also als erstes zu Deinem Code: Du löschst nicht einen Buchstaben an einem bestimmten Index sondern du löscht alle Buchstaben, die dem entsprechen, der an einem bestimmten index steht.

Teste es einfach einmal mit "aaaaaabcdefgaaaaa" und a soll dann mal 0 sein. Also Buchstabe an index 0 soll gelöscht werden....

Daher zwei Fragen:
a) was müsstest Du denn prüfen, damit nur der Buchstabe an einem bestimmten Index gelöscht wird? Sag es erst einmal in Worten und dann die Transformation in Code.

b) Ausgehend von a): Was müsstest Du denn prüfen, wenn du nun die zwei Grenzen bekommst und dazwischen alles gelöscht werden soll?


----------



## Kirby.exe (29. Nov 2019)

a) Wenn der Buchstabe beim String s anstelle i Zwischen Index bla und Index Bla liegt, ignorieren, ansonsten füge die Buchstaben zu Result hinzu
b) naja ob der Buchstabe beim String s halt an stelle i zwischen den beiden Indizes liegt, nur wüsste ich nicht wie da die Bedingung aussehen könnte


----------



## kneitzel (29. Nov 2019)

Bei a ging es mir um den bestehenden code, aber ok - du bist zwischen den indizes. Das ist ok.

Interessiert dich denn der Buchstabe? Musst Du den Buchstaben mit irgendwas vergleichen? Oder was musst Du vergleichen? Was ist dieses "i"? (Nimm immer aussagekräftige Namen! das erleichtert es dir evtl. auch!)


----------



## Kirby.exe (29. Nov 2019)

Naja also der Buchstabe perse interessiert jetzt nicht, da es ja um den Index im String geht, i ist ja die Laufvariable der For schleife und ich müsste ja den Buchstaben aus dem String an der i-ten zwischen den beiden Indizes liegt also beispielsweise ob Index 5 zwischen 4 und 6 liegt und wenn ja ignorieren oder?


----------



## Kirby.exe (29. Nov 2019)

Also etwa so oder?:


```
if (s.charAt(i) >= Index1 && s.charAt(i) <= Index2) {

ignore Stuff

}
```


----------



## kneitzel (29. Nov 2019)

Ja genau. Das hört sich gut an.
i ist somit der index des Buchstabens, der gerade betrachtet wird. Daher würde ich ihn auch index nennen oder - ich neige auch zu längeren Namen - currentIndex.
Jetzt wäre also die Frage: Wenn du untereGrenze und obereGrenze hast: Wie prüfst Du, ob currentIndex in dem Bereich ist?

Und bezüglich "Naja also der Buchstabe perse interessiert jetzt nicht," - was macht denn charAt? Wenn der Buchstabe nicht interessiert: Ist diese Methode für uns für den Vergleich wichtig?


----------



## Kirby.exe (29. Nov 2019)

Oh stimmt daran hab ich garnicht gedacht xD ich überlege mal eben


----------



## Kirby.exe (29. Nov 2019)

Also wenn meine Lösung stimmt, dann bin ich mal wieder an dem simpelsten Problem gescheitert, weil ich zu komplex gedacht habe  


```
if(a < index && index < b){
skip that shit
}
```


----------



## kneitzel (29. Nov 2019)

Ja, so sieht es sehr gut aus. Evtl. die < durch <= ersetzen, je nachdem, ob die Grenzen auch ignoriert werden sollen oder nicht. Oder eben umdrehen: Also `if (index < a || index > b) copycharacter`.

Und um den Bogen zurück zu Deinem ersten Code zu bringen. Wenn nur ein Zeichen an einer Stelle nicht kopiert werden soll, dann wäre das eben auch ohne diese charAt Aufrufe:

```
String result = "";
for (int i = 0; i <s.length(); i++) {
  if(i == a) {
    continue;
  } else {
    result += s.charAt(i);
  }
}
return result;
```

Und hier kann man das if/else auch vereinfachen indem man die Prüfung umdreht:


```
String result = "";
for (int i = 0; i <s.length(); i++) {
  if(i != a) {
    result += s.charAt(i);
  }
}
return result;
```


----------



## Kirby.exe (29. Nov 2019)

Danke für deine Tipps


----------



## Kirby.exe (29. Nov 2019)

Ich hätte noch ne Frage, hat zwar nichts wirklich heir mit dem Thread zu tun, aber irgendwie mache ich irgendwas Falsch, ich möchte gerne in einem Array den Vorgänger + die Zahl + den Nachfolger addieren und an der Stelle der Zahl wieder ins Array speichern. Um das zu tun habe ich folgende Operation gemacht, jedoch bekomme ich ein komisches Ergebnis heraus.


```
Unser Array: arr = {21,32,73,147}

arr[i] = (arr[i-1]+arr[i]+arr[i+1])/3;

Die Ausgabe die ich erwarte: 21.0 42.0 84.0 147.0
Die Ausgabe die ich bekomme: 21.0, 42.0, 87.33333333333333, 147.0
```


----------



## kneitzel (29. Nov 2019)

In dem Code teilst Du noch durch 3. Ich vermute einmal, dass Du dies schlicht vergessen hast, anzugeben.

Ansonsten ist die Berechnung korrekt für ein einzelnes Feld. Aber du stößt auf ein Problem:
Du hast 21, 32, 73, 147
Nun berechnest Du das für die zweite Zahl und hast 21, 42, 73, 147
Wenn Du nun für die 3. Zahl rechnest, dann ist die zweite Zahl schon 42 und nicht mehr 32.
Daher ist die neue Rechnung statt (32+73+147)/3 = 84 eben (42 + 73 + 147) / 3 = 87,3333333

Daher ist bei so Berechnungen aus meiner Sicht immer günstig, die Eingabe unverändert zu lassen. Das kann man z.B. durch clonen des Arrays erreichen:

```
double result[] = arr.clone(); // arr ist nicht gegeben, ist es double? Sonst ggf. anpassen.
for (int i=1; i<arr.length-1; i++) result[i] = (arr[i-1]+arr[i]+arr[i+1])/3;
return result;
```
(Im Browser geschrieben, daher evtl. Tippfehler vorhanden ... aber die Idee wird hoffentlich deutlich!)


----------



## Kirby.exe (29. Nov 2019)

Ah ich glaube du hast mir gerade nen echt guten Tipp gegeben, ich dummkopf speichere die Werte ja wieder im Selben Array und wundere mich über die Ausgabe  oh man ist mir gerade erst aufgefallen xD Dankeee


----------



## Kirby.exe (30. Nov 2019)

Ja gut irgendwie hab ich dass Gefühl entweder ich bin blind xD alle Test sind korrekt außer beim letzten. Er verrechnet sich beim Index 1.

Die Erwartete Ausgabe: 1.0, 1.5, 2.0, 2.0, 1.0
Die ausgegebene Ausgabe: 1.0, 1.0, 2.0, 2.0, 1.0

Mein Code:


```
double [] result = new double[arr.length];
        for(int i = 0; i < arr.length; i++) {
            if(arr[i] == arr[0] || arr[i] == arr[arr.length-1]) {
                result[i] += arr[i];
                continue;
            }
                result[i] = (arr[i-1]+arr[i]+arr[i+1])/3;
        }
        return result;
```


----------



## kneitzel (30. Nov 2019)

Erläutere mir doch bitte einmal, was Du mit `if(arr[i] == arr[0] || arr[i] == arr[arr.length-1])` prüfen willst....
(Tipp: Da ist der Fehler zu finden!)

Und was bitte willst Du mit `result[i] += arr[i];` genau machen? (Es funktioniert, aber erläutere mir mal, was er da macht incl. Info: Was ist vorher in der Variable und was ist nachher in der Variable ...)

Edit: Du hast mit nicht geschrieben, was die Eingabe ist, aber ich bin sicher, dass bei Index 1 die Zahl 1.0 zu finden ist bei dem Test


----------



## Kirby.exe (30. Nov 2019)

hab den Fehler gefunden  trotzdem thx


----------



## Kirby.exe (30. Nov 2019)

> if(arr_ == arr[0] || arr == arr[arr.length-1])_


_ der Code war etwas dumm  Manchmal sehe ich den Wald vor lauter Bäumen nicht xD_


----------



## kneitzel (30. Nov 2019)

Würdest Du Deine Lösung einmal zeigen? Würde mich interessieren, wie du es gelöst hast ...


----------



## Kirby.exe (2. Dez 2019)

Ok hier Bitteschön: 

```
public class Glaettung {

    public static double [] glaette(double [] arr) {
        double [] result = new double[arr.length];
        for(int i = 0; i < arr.length; i++) {
            if(i == 0 || i == arr.length-1) {
                result[i] += arr[i];
                continue;
            }
            result[i] = (arr[i-1]+arr[i]+arr[i+1])/3;
            
        }
        return result;
    }
    public static void main(String[] args) {
        double [] inputArray = {1, 1, 2.5, 2.5, 1};
        double [] result = glaette(inputArray);
        for(int i=0; i < result.length; i++) {
            System.out.print(result[i] + " ");
        }
    }
}
```


----------



## Kirby.exe (2. Dez 2019)

Ich hätte noch ne Frage @JustNobody wieso gibt ein Programm in Eclipse die Lösung aus die auch erwartet wird, aber die Test Umgebung gibt etwas komplett anderes aus xD

Also aus dieser Methode erhoffe ich mir ja dass er die Zeichen zwischen den zwei Indizes ignoriert, das tut er auch in Eclipse, in der Test Umgebung ignoriert er jedoch nur 1 Zeichen xD


```
static String delete(String s, int a, int b) {
        String result = "";
        for (int index = 0; index < s.length(); index++)
          {
            if(a <= index && index <= b ) {
                continue;
            }else {
                result += s.charAt(index);
            }
          }
        return result;
    }
```


----------



## kneitzel (2. Dez 2019)

Da bräuchte man mehr Informationen. Übliche Ursachen für so ein Verhalten:
- In der Testumgebung wird ein anderer Code ausgeführt (Code wurde nicht kopiert oder nicht übersetzt ... Ursachen können viele vorhanden sein. Prüfen, dass der Code richtig in der Testumgebung angekommen ist und dass dieser korrekt übersetzt wurde und natürlich: Das der übersetzte Code ausgeführt wird.)
- Es gibt eine andere Eingabe. Dann hätte man einfach unterschiedliche Dinge getestet.

Aus meiner Sicht ist hier immer hilfreich, wenn man ein Logging hat. Hier würde ich dir raten, Dir da mal ein Framework auszusuchen und zu nutzen. Dann hat man auf Wunsch immer ein Tracefile in dem man alles nachvollziehen kann.
Ansonsten hilft es Dir evtl., wenn Du einfach einige Ausgaben einbaust.


----------



## Kirby.exe (2. Dez 2019)

naja also ich habe mal geschaut ob vielleicht der String zu kurz ist, jedoch hat der eine Länge von 212 Zeichen, also daran liegt es schonmal nicht, das Problem mit dem Logging Tool, ich wüsste nicht ob es überhaupt möglich ist, etwas derartiges in die Testumgebung der Uni zu implementieren  ich schicke einfach mal die Eingabe 

Eingabe: 





> delete erhält als Parameter einen String, d.h. eine Zeichenkette, sowie zwei Positionsangaben, entfernt aus dem String alle Zeichen zwischen einschließlich den beiden Positionsangaben und gibt das Ergebnis zurück


Löschen: 





> Zwischen Index 42 und Index 65



Erwartete Ausgabe: 





> delete erhält als Parameter einen String, sowie zwei Positionsangaben, entfernt aus dem String alle Zeichen zwischen einschließlich den beiden Positionsangaben und gibt das Ergebnis zurück



Tatsächliche Ausgabe: 





> delete erhält als Parameter einen String, .h. eine Zeichenkette, sowie zwei Positionsangaben, entfernt aus dem String alle Zeichen zwischen einschließlich den beiden Positionsangaben und gibt das Ergebnis zurück


----------



## kneitzel (2. Dez 2019)

Hast du den Code geprüft? Stimmt der Aufruf (Also gibst Du 42 und 65 als Parameter an?) und der Code (Hast Du evtl. zwei mal den Parameter a geprüft in der if Bedingung?)?


----------



## Kirby.exe (2. Dez 2019)

Tatsächlich ließt die Testumgebung 2 mal den Wert 42 ein.... 


und ich wundere mich die ganze Zeit woran es liegen könnte  oh man da hat der Prof wahrscheinlich den falschen Parameter reingeschrieben xD


----------



## Kirby.exe (2. Dez 2019)

Jetzt ist alles richtig xD war args[3] und nicht args[2] xD

btw. danke für den Tipp  ich habe wirklich an alles gedacht, nur nicht daran, dass die Testumgebung vielleicht spinnt, merke ich mir für das nächste mal


----------



## mihe7 (2. Dez 2019)

@Kirby_Sike noch ein paar Anmerkungen zum Code aus #20:


```
public static double [] glaette(double [] arr) {
        double [] result = new double[arr.length];
        for(int i = 0; i < arr.length; i++) {
            if(i == 0 || i == arr.length-1) {
                result[i] += arr[i];
                continue;
            }
            result[i] = (arr[i-1]+arr[i]+arr[i+1])/3;
            
        }
        return result;
    }
```

Der Code ist schön kompakt, hat allerdings zwei Nachteile und einen diskussionswürdigen Punkt. 

1. Du brauchst nicht zu result addieren (nimm einfach = statt +=)
2. Du verwendest ein GOTO (continue). Das brauchst Du nicht, wenn Du ein else verwendest.


```
public static double [] glaette(double [] arr) {
        double [] result = new double[arr.length];
        for(int i = 0; i < arr.length; i++) {
            if(i == 0 || i == arr.length-1) {
                result[i] = arr[i];
            } else {
                result[i] = (arr[i-1]+arr[i]+arr[i+1])/3;
            }        
        }
        return result;
    }
```

Der Punkt, der diskussionswürdig ist: die Prüfung der Arraygrenzen wird in der Schleife jedesmal durchgeführt. Die Frage ist also, ob man das nicht rausziehen will.


```
public static double [] glaette(double [] arr) {
        double [] result = new double[arr.length];
        if (arr.length > 0) {
            result[0] = arr[0];
            result[arr.length-1] = arr[arr.length - 1];

            for (int i = 1; i < arr.length - 1; i++) {
                result[i] = (arr[i-1] + arr[i] + arr[i+1]) / 3;
            }
        }
        return result;
    }
```

Alle Lösungen haben übrigens gleich viele Codezeilen. Persönlich finde ich die letzte Variante auch einfacher zu verstehen, insbesondere, wenn man ein halbes Jahr später drauf schaut, aber das ist z. T. eine subjektive Angelegenheit.


----------



## Kirby.exe (2. Dez 2019)

Du hast recht, dein Code ist Ressourcen effizienter  Ich werde mir in einem Jahr sowieso meinen jetzigen Code anschauen und mir denken: "Was ist dass den für Spaghetti Code "


----------

