Nachbau der indexOf Methode

Status
Nicht offen für weitere Antworten.

ska3k

Aktives Mitglied
Hallo,
ich hab hier mal versucht, die indexOf Nachzuprogrammieren, doch er liefert mir ständig nur den Wert -1, also nix gefunden, zurück. Wenn er etwas findet, dann soll er mir die Position des ersten Zeichens vom Suchstring zurückgeben. Wenn das wort mehrmals im Szring ist, soll er nur den ersten Fundort zurückgeben.

Vielleicht kann mir einer von euch sagen, wo der Fehler bei mir genau liegt:


Code:
  private static String b_index(String s) {
    String ein;
    int check,count=0,pos=-1,n;
    
    System.out.print("Suchstring im anderen: ");
    ein=Eingabe.readString();
    

//    if (s.indexOf(ein)!=-1) {
//      return String.valueOf(s.indexOf(ein)+1);
//    } else {
//      return String.valueOf(s.indexOf(ein));
//    }

    for (int i=0; i<=s.length()-1; i++) {

      if (s.charAt(i)==ein.charAt(0)) {
        check=i;

        for (n=1; n<=ein.length()-2 && (s.length()-ein.length())>=0; n++,check++) {
          if (s.charAt(check)==ein.charAt(n)) {
            count++;
          }
        }
        
        if (count==ein.length() && pos==-1) {
          pos=i;
        }
        
        if (count!=ein.length()) {
          count=0;
          n=1;
        }
      }
    }

//    if (count==ein.length()) {
//      pos=count;
//    }
    
    return String.valueOf(pos);

  }
 
ska3k hat gesagt.:
Nachbau der indexOf Methode
Code:
static int indexOf(String source, String target, int fromIndex) {
    if (fromIndex >= source.length()) {
        return (target.length() == 0 ? source.length() : -1);
    }
    if (fromIndex < 0) {
        fromIndex = 0;
    }
    if (target.length() == 0) {
        return fromIndex;
    }
    char first  = target.charAt(0);
    int max = source.length() - target.length();
    for (int i = fromIndex; i <= max; i++) {
        if (source.charAt(i) != first) {
            while (++i <= max && source.charAt(i) != first){}
        }
        if (i <= max) {
            int j = i + 1;
            int end = j + target.length() - 1;
            for (int k = 1; j < end && source.charAt(j) == target.charAt(k); j++, k++){}
            if (j == end) {
                return i;
            }
        }
    }
    return -1;
}
 
Code:
for (int i=0; i<=s.length()-1; i++) { 

      if (s.charAt(i)==ein.charAt(0)) { 
        check=i; 

        for (n=1; n<=ein.length()-2 && (s.length()-ein.length())>=0; n++,check++) { 
          if (s.charAt(check)==ein.charAt(n)) { 
            count++; 
          } 
        } 
        
        if (count==ein.length() && pos==-1) { 
          pos=i; 
        } 
        
       if (count!=ein.length()) { 
          count=0; 
          n=1; 
        }
      } 
    }
was hamwa hier:

Beispiel:
s = "Wenn Fliegen hinter Fliegen fliegen, fliegen Fliegen Fliegen nach"
ein = "Fliegen"

(braucht nen substring der minimum 2x drin is 😀 )

so: check 0 ... count 0 ... pos -1 .. schleife rennt los

du suchst nun den ersten Buchstaben aus ein in s ... findest den am am index 5 und speicherst das in check (check = 5, i = 5) ... weiter gehts in der andern schleife

nun schaust du ob in s auch die richtigen Buchstaben aus ein folgen.

1. Schleifendurchlauf:
n = 1 ... check = 5 (das check++ in der schleifenbeschreibung wirkt erst nach 1. Durchlauf) daher nun folgendes ... die if-Bedingung prüft nun den Buchstaben "F" in s (da check++ nocht nich gewirkt hat und check somit immer noch 5 ist = Anfangsbuchstabe von ein) mit dem 2. Buchstaben in ein = "l" ... kann schonma nicht klappen. Weiterhin kannst du diese Schleife sofort abbrechen, wenn die Bedingung nicht gilt. Spart Laufzeit.

Solltest du das Wort dann doch mal gefunden werden, nach entsprechenden Umbaumaßnahmen, so kannst du, wenn du pos = i setzt auch gleich return pos ranhängen und die Suchen abbrechen.

Ich will nun nicht behaupten, dass das des Rätsels Lösung ist, dennoch ein Anfang um dein Problem in Griff zu bekommen. Hatte nich soviel Zeit das genauer durchzuspinnen.
 
Hiho,

kann man das nich auch relativ kompakt à la:

Code:
private static int myIndexOf(String aSource, String aFind) {
		
		if (aFind.length() > aSource.length()) return -1;
		
		char[] source = aSource.toCharArray();
		char find = aFind.charAt(0);
		
		int border = source.length - aFind.length();
		
		for(int i = 0; i <= border; i++) {
			
			if (source[i] == find) {
				
				String s = aSource.substring(i, i + aFind.length());
				
				if (s.equals(aFind)) return i;
			}
		}
		
		return -1;		
	}

schreiben!?

bye Saxony
 
Das wäre eine Lösung des Problems 😉

Das Prolem ist aber, dass ich nur die charAt und length Methode verwenden will. Mit der substring ist es natürlich leicht zu realisieren.
 
Auch, wenn der String im source string drin ist, bringt er nicht gefunden, als -1.

Code:
  private static String b_index(String source, String target) {
    int check,count=0,pos=-1,n;


    for (int i=0; i<=source.length()-1; i++) {

      if (source.charAt(i)==target.charAt(0)) {
        check=i;
        check++;
        
        for (n=1; n<=target.length()-2 && (source.length()-target.length())>=0; n++,check++) {
          if (source.charAt(check)==target.charAt(n)) {
            count++;
          } else {
            break;
          }
        }

        if (count==target.length()) {
          return String.valueOf(i);
        }

        if (count!=target.length()) {
          count=0;
          n=1;
        }
      }
    }

    return String.valueOf(-1);

  }


Hab mich an deinen Änderungen gehalten, vlt findest du noch den restlichen Fehler 😉
 
hm mach mal in der 2. schleife bis <= target.length() -1 ... weil mit -2 läuft die schleife nie solange, das count jemals der länge des wortes entsprechen könnte, weiterhin ist count bereits mit gefundenem index i auf 1 zu setzen
 
Code:
    for (int i=0; i<=source.length()-1; i++) {

      if (source.charAt(i)==target.charAt(0)) {
        check=i;
        check++;
        
        for (n=1; n<=target.length()-1 && (source.length()-target.length())>=0; n++,check++) {
          if (source.charAt(check)==target.charAt(n)) {
            count++;
          } else {
            break;
          }
        }

        if (count==target.length()) {
          return String.valueOf(i);
        }

        if (count!=target.length()) {
          count=1;
          n=1;
        }
      }
    }


Klappt auch nicht
 
dann lass dir ausgeben was in der 2. forschleife jeweils getestet wird und wie die count und check-werte liegen etc.
musst den fehler ja auch in der ausgaben finden können
 
Hiho,

also komplett straight forward kommt soetwas bei mir raus:

Code:
private static int b_index(String source, String target) {

	for (int i = 0, n = 1, sL = source.length(), tL = target.length(); i <= sL - tL; i++, n = 1) {

		if (source.charAt(i) == target.charAt(0)) {

			for (int j = 1; j < tL; j++) {

				if (source.charAt(i + j) == target.charAt(j)) n++;
				else break;
			}
			if (n == tL) return i;
		}
	}
	return -1;
}

KA für was du den ganzen Variablendschungel brauchst! 😉

[edit]
Wenn man n immer gleich auf 1 setzt, kann man in der inneren Schleife noch eine Iteration, eine Addition, zwei charAts, einen Vergleich, ein Inkrement von j und wenn ja noch ein Inkrement von n sparen. 😀
[/edit]

bye Saxony
 
Der Code von Saxony ähnelt meinem Beispiel, aber in diesem Fall krieg ich eine Exception:
Code:
String find = "";
...
int index = b_index("acb", find);
StringIndexOutOfBoundsException: String index out of range: 0
Gruß,
André
 
muss aber schon sagen, das ich den ersten for-schleifen-kopf von Saxony nicht wirklich appetitlich finde ^^ .. nur weil mans in eine zeile schreiben kann, heisst es ja nich das es sich besser liest ^^
 
Hiho,

ich sagte ja straight forward - also so tippen wie ich dachte das es funktioniert.

Mit Sicherheitsüberprüfung und Variablenaufdrösselung:

Code:
private static int b_index(String source, String target) {

	if ((source == null) || (target == null)) return -1;

	final int sL = source.length();
	final int tL = target.length();

	if ((tL == 0) || (tL > sL)) return -1;

	for (int i = 0, n = 1; i <= sL - tL; i++, n = 1) {

		if (source.charAt(i) == target.charAt(0)) {

			for (int j = 1; j < tL; j++) {

				if (source.charAt(i + j) == target.charAt(j))
					n++;
				else
					break;
			}
			if (n == tL) return i;
		}
	}
	return -1;
}

So aber noch genauer kann ich es nun nicht mehr hinschreiben! 🙂

bye Saxony
 
Riesen Dank wirklich an euch alle, jetzt klappt perfekt! Auch wenn es bis dahin ein wenig gedauert hat 😉

Nur noch eine Frage, was deutet dieses source == null? Ist das das gleich, als wenn ich source == "" schreibe?
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben