indexOf-Methode

Hallo zusammen:

Ich soll eine Methode static int indexOf (int []s, int[]a) schreiben, die den Startindex des Teilarrays s im Array a liefert. Falls s nicht in a enthalten ist, soll -1 geliefert werden und man soll davon ausgehen, dass keines der Arrays null ist.

Bsp:

indexOf ({3,4}, {1,2,3,4,5}) =>2

Kann mir hier jemand weiterhelfen? Die Aufgabe hört sich eig. nicht so schwer an, doch ich komme iwie nicht weiter.
Über jegliche Tipps bin ich sehr dankbar. Vielen Dank!

Liebe Grüße! :slight_smile:

Fertige Lösungen bekommst du hier nicht serviert.
Poste deine Ansätze und Probleme die sich da ergeben, dann hilft man dir hier gern.

Tschuldigung, ich wollte keine fertige Lösung. Aber ich habe das Problem, dass ich ja erstmal überprüfen muss, ob Teilarray s in Array a enthalten ist. Gibt es da in Java vielleicht einen Operator für?

Nein den gibt es nicht. Aber das lässt sich relativ leicht mit zwei Schleifen lösen.

Ok, vielen Dank schonmal! :slight_smile:

*** Edit ***

Da, ich noch Anfängerin in Java bin, hab ich in manchen Sachen noch Probleme. Ich hoffe auf Verständnis :wink:

Ich habe mich mal daran versucht, zu zeigen, ob Teilarray s in Array a vorhanden ist (leider nicht sehr erfolgreich!) Wäre toll, wenn mir jemand weiterhelfen könnte!


public class ArrayIndex {

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 4, 5};
        int[] s = {3, 4};

    }

    public static boolean contains(int[] a, int[] s) {

        for (int i = 0; i < a.length; i++) {
            if (a** == s**) {

                return true;

            } else {

                return false;
            }

        }

    }

Danke!

Sobald das Element a** mit dem Element s** überein stimmt, gibt contains true zurück.
Das ist vermutlich nicht ganz im Sinne des Erfinders.
Überlege dir erst mal, was du genau tun willst und schreib dir das auf, z.B. in Pseudocode.
Wenn du denkst, dass das richtig ist, dann überlege wie du das in Java umsetzen kannst.

…Nimm das erste element von a und vergleiche nacheinander mit den Elementen von s.
Sobald dieses erste Element von a mit einem Element von s überein stimmt, dann prüfe,
ob auch die weiteren Elemente von a mit s übereinstimmen…usw.

Ok! Nein, das ist wirklich nicht im Sinne des Erfinders. Also es ist ja so, dass wenn a** mit s[j] übereinstimmt, soll true zurückgegeben werden. Oder bin ich jetzt ganz falsch?

Wie gesagt, du brauchst zwei Schleifen um festzustellen, ob ein Array in einem anderen vorhanden ist. Außerdem beendet sich deine Schleife nach dem ersten Durchlauf.

In Pseudocode könnte das so aussehen:

{
  maxIndex = min(a.length, b.length);

  for (i =0; i < a.length - b.length; i++) {
    numberOfMatches = 0;
    for (j = i; j < maxIndex; j++) {
      if (a[j] != b[j]) {
        break;
      }
      numberOfMatches++;
    }

    if (numberOfMatches == b.length) {
      return true;
    }
  }

  return false;
}```
Wenn man den inneren Teil noch in eine weitere Methode auslagert wird der Code nochmal etwas schicker, aber ich denke die Grundidee dahinter sollte rüberkommen.

Ok, danke! Problem: Ich hab noch nie mit Pseudocode gearbeitet.

versuch es einfach in deinen Worten zu sagen, was das Programm nacheinander tun soll…
Das ist Pseudocode, nichts weiter.

Theoretisch: Ist es wichtig, ob Doppelte Zahlen im Array sind?

Meine Frage bezieht sich auf das

break;```

Ich habe ein Programm, das läuft nur stimmt etwas mit dem zweiten return-statement nicht (wenn das Teilarray nicht enthalten ist und -1 ausgegeben werden soll)



public class Test2 {
   public static void main(String[] args) {
        int tArray1[] = {3, 4, 6, 7, 8};
           
       
        
        int tArray2[] = {4};
        
        indexOf(tArray1, tArray2);
    }

    public static int indexOf(int a[] , int s[]){
        boolean isCorrect;
    for (int i = 0; i < a.length - s.length; i++) {
        isCorrect = true;
        for (int j = 0; j < s.length; j++) {
            if (a[i + j] != s[j]) {
                isCorrect = false;
                break;
            }
        }
        
        
        if (isCorrect) {
            
            System.out.println ("Startindex des Teilarrays:"+i);
        
    }
          }
  
    return -1;
   
 
   
    }
}

Vielleicht kann da jemand noch weiterhelfen. Danke!

*** Edit ***

Also ich hab jetzt so gut wie alles noch 20x durchprobiert, aber ich finde meinen Fehler in der return-Anweisung nicht! Kann jemand bitte weiterhelfen? Danke!

Wenn etwas ausgegeben werden soll, dann wäre z.B. ein syso nicht schlecht…
Also sowas
System.out.println(indexOf(tArray1, tArray2));
und vielleicht müsstest du auch den gefundenen Index returnen…
Ich vermute das wolltest du da tun…´


				System.out.println ("Startindex des Teilarrays:"+i);
				return(i);

			}```

Java bringt eine für diese Aufgabe praktische Utility-Klasse Arrays mit.


public class ArrayContains {

    public static void main(String[] args){
        int[] a = {2,3};
        int[] b = {0,1,2,1,3,4,5};

        indexOf(a, b);
    }

    private static int indexOf(int[] a, int[] b) {
        for(int i = 0; i<b.length-a.length;i++) {
            if(Arrays.equals(a, Arrays.copyOfRange(b, i, i + a.length))) {
                return i;
            }
        }
        return -1;
    }
}```

Aber das gibt auch nichts aus Majora :smiley:

	public static void main(String[] args) {
		int tArray1[] = {3, 4, 6, 6, 7, 8};
		int tArray2[] = {6,7};
		System.out.println("Startindex des Teilarrays: "+ indexOf(tArray1, tArray2));
	}

	public static int indexOf(int a[] , int s[]){
		boolean isCorrect;
		for (int i = 0; i < a.length - s.length; i++) {
			isCorrect = true;
			for (int j = 0; j < s.length; j++) {
				if (a[i + j] != s[j]) {
					isCorrect = false;
					break;
				}
			}
			if (isCorrect) {
				return(i);
			}
		}
		return -1;
	}
}```

Ich hab es hinbekommen, danke :smiley:

Mein Vorschlag: umwandeln der Elemente a** und s** in Strings und dann mit indexOf die Position von s** in a** ermitteln.

public class indexof {

	public static void main(String[] args) {
	      int[] a = new int[]{1, 2, 3, 4, 5};
	      int[] s = new int[]{3, 4};
	 
	 System.out.println(indexOf(a,s));	
	}
	    public static int indexOf (int []a, int[]s) {
             
              // Vorarbeit
	    	        String aa = new String();
	   	 	int q = a.length;
	   	 	for(int i=0;i<q;i++){
	   	 		aa+=(Integer)a**;
	   	 	}
	   	 	String ss = new String();
	   	 	 q = s.length;
	   	 	for(int i=0;i<q;i++){
	   	 		ss+=(Integer)s**;
	   	 	}
	    	// der eigentliche Vergleich
	    	int result=0;
	    		result = aa.indexOf(ss);
	    	return result;
	    }

result =-1 Array2 nicht in Array1 enthalten

das würde ich aber mal ganz schnell wieder vergessen, vor allem in einer so falschen implementierung wie deiner

denn deine methode würde auch was liefern wenn man folgende arrays nutzt
a= {1, 234, 5}
b= {2,3,4}

grundsätzlich

  1. „new String()“ nutzt man NICHT ! never ever und überhaupt gar nicht !
  2. String-concatierungen entweder mit String.concat() oder besser gleich mit einem StringBuilder
  3. wenn man mit arrays arbeitet sollte man die einzelnen elemente schon irgendwie von ein ander trennen, z.b. mit nem komma oder nem slash
  4. sollte man unnötige casts vermeiden, denn bei deinem code würde eh auto-boxing greifen, die expliziten casts können wegfallen da der compiler eh einen StringBuilder draus baut, und der hat methode für primitives

kurz : idee mist und code noch mistiger

  StringBuilder sb1 = new StringBuilder();
  for (int i : ia1) {
    sb1.append(i);
    sb1.append(' ');
  }
  StringBuilder sb2 = new StringBuilder();
  for (int i : ia2) {
    sb2.append(i);
    sb2.append(' ');
  }
  return sb1.indexOf(sb2.toString()); // sb1 der längere String
}

public int indexOf(int[] ia1, int[] ia2) {
  for (int i = 0; i < ia1.length - ia2.length() + 1 /* problematisch */ ; i++) {
    for (int j = i; j < i + ia2.length(); j++) {
      if (ia1[j] != ia2[j - i]) {
        break; // springt aus for (int j.... raus
      }
      return i;
    }
  }
  return -1;
}```

*** Edit ***

Schnell noch ein paar Tests gemacht, dieses hier funktioniert wunderbar:

```    public static int indexOf(int[] ia1, int[] ia2) {
        for (int i = 0; i < ia1.length - ia2.length + 1 /* problematisch */; i++) {
            for (int j = i; j < i + ia2.length; j++) {
                if (ia1[j] != ia2[j - i]) {
                    break; // springt aus for (int j.... raus
                }
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] a = {1};
        int[] b = {};
        System.out.println(indexOf(a, b)); // -1
        b = a;
        a = new int[]{};
        System.out.println(indexOf(a, b)); // -1
        a = b;
        System.out.println(indexOf(a, b)); //  0```.

Insofern, wenn new int[]{} gesucht ist, immer -1 zurückgegeben wird / werden soll. Das müsste man mit dem Quelltext von indexOf in der API von JAVA abgleichen, denn diese wissen ja, was man sich unter indexOf vorzustellen haben soll.

*** Edit ***

Edit 2: Oh je, war ein Denkfehler drin:

```    public static int indexOf(int[] ia1, int[] ia2) {
        a:
        for (int i = 0; i < ia1.length - ia2.length + 1 /* problematisch */; i++) {
            for (int j = i; j < i + ia2.length; j++) {
                if (ia1[j] != ia2[j - i]) {
                    continue a; // fährt mit Schleife mit Label a fort (äußere Schleife)
                }
            }
            return i;
        }
        return -1;
    }```.