# Erklärung search Methode



## JavaIsTheBest (3. Mai 2016)

Hallo,
ich habe hier zwei Aufgabenstellungen mit Lösungen. Die Lösung hab ich mir noch nicht angeschaut, weil ich es erstmal selbst probieren will.
Ich verstehe nicht, was ich in den beiden Teilaufgaben machen soll.


----------



## Flown (3. Mai 2016)

Was genau verstehst du daran nicht?


----------



## JStein52 (3. Mai 2016)

Ich würde zuerst die zweite Teilaufgabe machen, mir überlegen wie dieses Array aussehen muss und wie man es entsprechend initialisiert (ein Bild ist ja schon da)  und dann die search-Methode ...
Und ein Tip: In der Klasse String gibt es die Methode contains(...) mit der du prüfen kannst ob ein String in einem anderen enthalten ist. Jetzt musst du dir nur die Schleife überlegen und in welchem Teil des Arrays du deinen Suchstring suchen musst.  Auch hier wieder der Tip: das letzte Elelemnt eines Arrays hat den Index meinArray.length-1


----------



## JavaIsTheBest (5. Mai 2016)

Warum wird mir hier kein true oder false in der Konsole ausgegeben, wenn ich die isPartof Methode verwende?



Spoiler: isPartOf





```
public class Arrays {
   
    public static void print(String[][] a){
        for(int i=0;i<a.length;i++){
            for(int j=0;j<a[i].length;j++){
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static boolean isPartOf(String s1, String s2){
        if(s1=="") return true;
        String sub="";
        for(int i=0;i<s1.length();i++){
            for(int j=0;j<s2.length();j++){
                if(sub==s1) return true;
                else if(s1.charAt(i)!=s2.charAt(j)){
                    sub="";
                    continue;
                }
                else{
                    sub+=s2.charAt(j);
                }
            }
               
        }
        return false;
    }
    /*public static String[][] search(String[][] a){
       
    }*/
   
   
    //Main
    public static void main(String[][] args){
        System.out.print(isPartOf("bc", "abcd"));
    }
}
```


----------



## Meniskusschaden (5. Mai 2016)

Vermutlich rufst du gar nicht dein Programm auf, sondern ein anderes, denn du hast keine gültige main-Methode. Da ist ein eckiges Klammernpaar zu viel.


----------



## JavaIsTheBest (5. Mai 2016)

Ich hab jetst eine zusätzlich Testklasse erstellt. Warum kann ich die Methode nicht aufrufen, obwohl Sie public und static ist?

public class Test {

   public static void main(String[] args) {
     System.out.print(isPartOf("bc", "abcd"));
   }

}


----------



## JavaIsTheBest (5. Mai 2016)

Meniskusschaden hat gesagt.:


> Vermutlich rufst du gar nicht dein Programm auf, sondern ein anderes, denn du hast keine gültige main-Methode. Da ist ein eckiges Klammernpaar zu viel.



Wo ist ein eckiges Klammerpaar zuviel?


----------



## JavaIsTheBest (5. Mai 2016)

Warum wird hier ein eindimensionales Array benutzt und dann ein zweidimensionales Array zurückgegeben.


----------



## mrBrown (5. Mai 2016)

JavaIsTheBest hat gesagt.:


> Warum wird hier ein eindimensionales Array benutzt und dann ein zweidimensionales Array zurückgegeben.


Da werden doch nur zweidimensionale Arrays benutzt?


----------



## JavaIsTheBest (5. Mai 2016)

In der letzten for Schleife steht 
b[n++] = a_;

Das ist doch ein Eindimensionales Array;_


----------



## mrBrown (5. Mai 2016)

b und a sind zweidimensionale Arrays, b[n++] und a_ sind jeweils Zeilen dieser Arrays._


----------



## Meniskusschaden (5. Mai 2016)

JavaIsTheBest hat gesagt.:


> Wo ist ein eckiges Klammerpaar zuviel?


Hier:


JavaIsTheBest hat gesagt.:


> ```
> public static void main(String[][] args){
> ```


Das müsste so aussehen:
	
	
	
	





```
public static void main(String[] args){
```


----------



## Meniskusschaden (5. Mai 2016)

mrBrown hat gesagt.:


> b und a sind zweidimensionale Arrays, b[n++] und a_ sind jeweils Zeilen dieser Arrays._


Genau. Manchmal ist es hilfreich, sich zweidimensionale Arrays als eindimensionale Arrays vorzustellen, deren Elemente ebenfalls eindimensionale Arrays sind, deren Elemente die Elemente sind, um die es eigentlich geht. Davon wird bei dieser Aufgabe Gebrauch gemacht.


----------



## JavaIsTheBest (5. Mai 2016)

Warum wird bei der isPartOf Methode kein true zurückgeliefert? Ich habe schon gedebuggt und meiner Meinung nach, müsste schon true rauskommen, da sub==s1 (letzte Zeile).



Spoiler: ispartof





```
public class Arrays {
   
    public static void print(String[][] a){
        for(int i=0;i<a.length;i++){
            for(int j=0;j<a[i].length;j++){
                System.out.print(a[i][j]+" ");
            }
            System.out.println();
        }
    }
    public static boolean isPartOf(String s1, String s2){
        if(s1=="") return true;
        int n=0;
        String sub="";
        outer: for(int i=0;i<s1.length();i++){
                for(int j=0+ ++n;j<s2.length();j++){
                    if(sub==s1) return true;
                    else if(s1.charAt(i)!=s2.charAt(j)){
                        sub="";
                        i=0;
                        continue;
                    }
                    else{
                        sub+=s2.charAt(j);
                        n=j;
                        continue outer;
                    }
                }
                   
            }
        return sub==s1;
    }
    /*public static String[][] search(String[][] a, String s){
        int n=0;
        for(int i=0;i<a.length;i++){
            if(isPartOf(s,a[i][a[i].length-1])){
                n++;
            }
        }
        String[][] b=new String[n][];
        for(int i=0;i<n;i++){
            for(int j=0;j<)
        }
    }*/
   
    public static void main(String[] args) {
        System.out.print(isPartOf("bc", "abcd"));
    }
}
```


----------



## JStein52 (5. Mai 2016)

meintest du vielleicht sub.equals(s1) ?? Das kommt übrigens dort zweimal vor.


----------



## Meniskusschaden (5. Mai 2016)

Der Algorithmus wird aber noch nicht funktionieren, falls der enthaltene String ganz am Anfang vorkommt.


----------



## JavaIsTheBest (5. Mai 2016)

Meniskusschaden hat gesagt.:


> Der Algorithmus wird aber noch nicht funktionieren, falls der enthaltene String ganz am Anfang vorkommt.



Bin ich an die Sache falsch ran gegangen oder was sollte ich anders machen?


----------



## Meniskusschaden (5. Mai 2016)

Ich finde deinen Algorithmus schwer verständlich und habe ihn deshalb nicht vollständig durchgearbeitet. Bei der inneren Schleife gibt es aber eine relativ offensichtliche Auffälligkeit:
	
	
	
	





```
for(int j=0+ ++n;j<s2.length();j++){
```
Da n vor Schleifenbeginn auf 0 gesetzt wurde, startet j mit dem Wert 1. Die innere Schleife beginnt also erst bei dem zweiten Buchstaben.


----------



## JavaIsTheBest (6. Mai 2016)

Ich habs rausbekommen. Allerdings ist meine Lösung länger und ich hab das nur mithilfe des Debuggers hinbekommen. 



Spoiler: ispartof





```
public static boolean isPartOf(String teilstring, String langerstring){
        if(teilstring=="") return true;
        int teilstringLaenge=0;
        int zeiger=0, j=0;
        outer:for(int i=0;i<teilstring.length();i++){
                j+=zeiger;
                for(j=zeiger;j<langerstring.length();j++){
                    if(teilstring.charAt(i)!=langerstring.charAt(j)){
                        teilstringLaenge=0;
                        zeiger++;
                        continue;
                    }
                    else{
                        teilstringLaenge++;
                    }
                    zeiger++;
                    continue outer;
            }
        }
        return(teilstringLaenge==teilstring.length());
```


----------



## VfL_Freak (6. Mai 2016)

Moin,



JavaIsTheBest hat gesagt.:


> Warum wird mir hier kein true oder false in der Konsole ausgegeben, wenn ich die isPartof Methode verwende?


Strings werden nicht mit '==' verglichen, sondern mit derMethode 'equals' !!
Wirf' mal einen Blick in die API !!

Gruß Klaus


----------



## JavaIsTheBest (6. Mai 2016)

Warum hat der Compiker aber nicht gemeckert?


----------



## VfL_Freak (6. Mai 2016)

Weil es ihn nicht interessiert!!
Ein Stringvergleich mit '==' ist ja syntaktisch korrekt, nur wird dabei eben *nicht *der _Inhalt der Strings_ verglichen, sondern die _Objektreferenz_!!

hier eine längere Erklärung: http://www.java-blog-buch.de/0302-strings-vergleichen/

gruß Klaus


----------



## Meniskusschaden (6. Mai 2016)

Das stimmt alles. Das Programm von @JavaIsTheBest funktioniert aber "durch Zufall" trotzdem, denn der einzige enthaltene Stringvergleich liefert aus oben genannten Gründen immer false, so dass die Methode nicht vorzeitig verlassen wird. Der normale Algorithmus liefert für einen leeren String aber ohnehin das gewünschte true zurück. Die Zeile kann also ersatzlos gestrichen werden.

Die Zeile`j+=zeiger;`ist übrigens auch überflüssig, denn in der darauf folgenden Zeile wird j ohnehin neu initialisiert.

Insgesamt finde ich die neue Version besser lesbar als die alte (bessere Namen, keine Manipulation von Laufvariablen). Ich konnte die Algorithmus-Idee relativ schnell erkennen, was ich vorher nicht wirklich konnte. Trotzdem finde ich die Aufgabe so komplex, dass man sie in Teilaufgaben untergliedern sollte, etwa durch das Auslagern des Tests, ob der Teilstring an einer festen Position des langen Strings enthalten ist. Das könnte beispielsweise so aussehen:

```
private static boolean isPartOf(String subString, String fullString) {
        for (int fullStringPos=0; fullStringPos<fullString.length(); fullStringPos++) {
            if (isMatchingAt(subString, fullString, fullStringPos))
                return true;
        }
        return false;
    }

    private static boolean isMatchingAt(String subString, String fullString, int fullStringPos) {
        if (subString.length()>fullString.length()-fullStringPos)
            return false;
        for (int subStringPos=0; subStringPos<subString.length(); subStringPos++, fullStringPos++)
            if (subString.charAt(subStringPos)!=fullString.charAt(fullStringPos))
                return false;
        return true;
    }
```


----------



## Flown (6. Mai 2016)

@Meniskusschaden Laufvariablen sollten immer kurz gehalten werden, denn sie sind eigentlich definiert durch den Initialwert und der Abbruchbedingung der Schleife. Also ist i, j, k, ... ausreichend.
Nachdem hier auch schon mit Labels gearbeitet wurde, würde ich eher sowas vorziehen:

```
private static boolean isPartOf(String s, String part) {
  outer: for (int i = 0; i <= s.length() - part.length(); i++) {
    for (int j = 0; j < part.length(); j++) {
      if (s.charAt(i + j) != part.charAt(j)) {
        continue outer;
      }
    }
    return true;
  }
  return false;
}
```


----------



## Meniskusschaden (6. Mai 2016)

@Flown Mit Labels kann ich mich eigentlich nicht anfreunden, aber trotzdem ist das eine gut lesbare Lösung. Die Schwierigkeit bei der Aufgabe ist ja, dass man drei Zeichenpositionen innerhalb der beiden Strings koordinieren muß, was das ganze unübersichtlich macht. Die Verwendung von i+j in der inneren Schleife ist aber so prägnant, dass man den Algorithmus schnell versteht.


----------

