Soru Bir dizedeki tüm karakter oluşumlarının indeksleri


Aşağıdaki kod 2 basılacaktır

String word = "bannanas";
String guess = "n";
int index;
System.out.println( 
    index = word.indexOf(guess)
);

"Bannanas" dizesindeki "n" ("tahmin") dizinlerinin tümünü nasıl alacağımı bilmek isterim

Beklenen sonuç şöyle olurdu: [2,3,5]


76
2018-02-17 20:46


Menşei




Cevaplar:


Bu, pozisyonların listesini -1 sonunda Peter Lawrey'in çözümü  vardır vardı.

int index = word.indexOf(guess);
while (index >= 0) {
    System.out.println(index);
    index = word.indexOf(guess, index + 1);
}

Ayrıca bir for döngü:

for (int index = word.indexOf(guess);
     index >= 0;
     index = word.indexOf(guess, index + 1))
{
    System.out.println(index);
}

[Not: eğer guess Tek bir karakterden daha uzun olabilir, o zaman, analiz ederek guess dize word Yukarıdaki döngülerden daha hızlı yapar. Böyle bir yaklaşımın ölçütü Boyer-Moore algoritması. Bununla birlikte, böyle bir yaklaşımı kullanmanın lehine olacak şartlar mevcut görünmemektedir.]


120
2018-02-17 21:00





Aşağıdakileri deneyin (Sonunda -1 yazmıyor!)

int index = word.indexOf(guess);
while(index >= 0) {
   System.out.println(index);
   index = word.indexOf(guess, index+1);
}

17
2018-02-17 20:48



indexOf'un en iyi kullanımı! - asgs
her zaman sonunda -1 yazdırabilirsiniz - smas
@Peter Cevabınız için çok teşekkür ederim, doğru görünüyor, ama bu aslında Java ile ilk günümde bu yüzden sonuçtan biraz şaşkınım, sonuçta çıktı -1 gibi görünüyor ve nedenini tam olarak anlamadım! Teşekkürler!! - Trufa
@Trufa: Sonuçta her zaman -1 basar indexOf karakter bulunamadığı zaman -1 değerini döndürür. - ColinD
@Trufa - yazdırdığı nedeni -1 sonunda bu do döngü vücudu yürütür ve sonra keşfeder ki index == -1 sonlandırmada while. - Ted Hopp


String string = "bannanas";
ArrayList<Integer> list = new ArrayList<Integer>();
char character = 'n';
for(int i = 0; i < string.length(); i++){
    if(string.charAt(i) == character){
       list.add(i);
    }
}

Sonuç şu şekilde kullanılacaktır:

    for(Integer i : list){
        System.out.println(i);
    }

Veya bir dizi olarak:

list.toArray();

5
2018-02-17 20:47





int index = -1;
while((index = text.indexOf("on", index + 1)) >= 0) {
   LOG.d("index=" + index);
}

2
2018-03-28 19:23





String word = "bannanas";

String guess = "n";

String temp = word;

while(temp.indexOf(guess) != -1) {
     int index = temp.indexOf(guess);
     System.out.println(index);
     temp = temp.substring(index + 1);
}

1
2018-02-17 20:51



Genel fikir doğru ama word.substring(word) derleme yapmaz. : P - Peter Lawrey
@Peter, düzeltme için teşekkürler. - asgs
Hala bir sorun var: sürekli olarak 2 yazdırır. - POSIX_ME_HARDER
Tanrım, buraya gönderdiğim her şeyi javak etmeye ihtiyacım var. - asgs


Java9 ile, biri yararlanabilir iterate(int seed, IntPredicate hasNext,IntUnaryOperator next) aşağıdaki gibi:-

List<Integer> indexes = IntStream
          .iterate(word.indexOf(c), index -> index >= 0, index -> word.indexOf(c, index + 1))
          .boxed()
          .collect(Collectors.toList());
System.out.printlnt(indexes);

1
2018-02-03 03:06





    String input = "GATATATGCG";
    String substring = "G";
    String temp = input;
    String indexOF ="";
    int tempIntex=1;

    while(temp.indexOf(substring) != -1)
    {
        int index = temp.indexOf(substring);
        indexOF +=(index+tempIntex)+" ";
        tempIntex+=(index+1);
        temp = temp.substring(index + 1);
    }
    Log.e("indexOf ","" + indexOF);

0
2018-03-07 15:03



... DNA sekanslarını arayan kod mu? ¿? ¿XD - kaytes


Ayrıca, bir String'deki bir String'in tüm indekslerini bulmak istiyorsanız.

int index = word.indexOf(guess);
while (index >= 0) {
    System.out.println(index);
    index = word.indexOf(guess, index + guess.length());
}

0
2017-09-17 11:25



Bu ilginçtir, "tüm oluşumlar" anlamında bir belirsizlik yaratır. Eğer guess  oldu "aba" ve word oldu "ababa", eğer açık değil guess bir veya iki kez oluşur word. (Yani, birinin bulabileceği net guess iki ayrı konumdan başlayarak, ancak olaylar birbiriyle örtüştüklerinden, her ikisinin de sayılmasının gerekip gerekmediği açık değildir.) Bu cevap, örtüşen olayların ayrı sayılmadığı görüşünü alır. Tabii ki, OP'nin ifadesi güçlü bir şekilde guess Her zaman 1 uzunluğuna sahip olacak, belirsizlik ortaya çıkmaz. - Ted Hopp


Bu problemle karşılaştım, bu yöntemle gelene kadar.

public static int[] indexesOf(String s, String flag) {
    int flagLen = flag.length();
    String current = s;
    int[] res = new int[s.length()];
    int count = 0;
    int base = 0;
    while(current.contains(flag)) {
        int index = current.indexOf(flag);
        res[count] = index + base;
        base += index + flagLen;
        current = current.substring(current.indexOf(flag) + flagLen, current.length());
        ++ count;
    }
    return Arrays.copyOf(res, count);
}

Bu yöntem, bir dizgede herhangi bir uzunlukta herhangi bir işaretin dizinlerini bulmak için kullanılabilir, örneğin:

public class Main {

    public static void main(String[] args) {
        int[] indexes = indexesOf("Hello, yellow jello", "ll");

        // Prints [2, 9, 16]
        System.out.println(Arrays.toString(indexes));
    }

    public static int[] indexesOf(String s, String flag) {
        int flagLen = flag.length();
        String current = s;
        int[] res = new int[s.length()];
        int count = 0;
        int base = 0;
        while(current.contains(flag)) {
            int index = current.indexOf(flag);
            res[count] = index + base;
            base += index + flagLen;
            current = current.substring(current.indexOf(flag) + flagLen, current.length());
            ++ count;
        }
        return Arrays.copyOf(res, count);
    }
}

0
2017-09-10 19:14





Ayrıldığım dizeleri ayırmak için bir sınıf. Sonunda kısa bir test yapılır.

SplitStringUtils.smartSplitToShorterStrings(String str, int maxLen, int maxParts) mümkünse kelimeleri kırabilmeden boşluklara bölünecek ve eğer değilse, maxLen'e göre indekslerle bölünecektir.

Nasıl bölüneceğini kontrol etmek için sağlanan diğer yöntemler: bruteSplitLimit(String str, int maxLen, int maxParts), spaceSplit(String str, int maxLen, int maxParts).

public class SplitStringUtils {

  public static String[] smartSplitToShorterStrings(String str, int maxLen, int maxParts) {
    if (str.length() <= maxLen) {
      return new String[] {str};
    }
    if (str.length() > maxLen*maxParts) {
      return bruteSplitLimit(str, maxLen, maxParts);
    }

    String[] res = spaceSplit(str, maxLen, maxParts);
    if (res != null) {
      return res;
    }

    return bruteSplitLimit(str, maxLen, maxParts);
  }

  public static String[] bruteSplitLimit(String str, int maxLen, int maxParts) {
    String[] bruteArr = bruteSplit(str, maxLen);
    String[] ret = Arrays.stream(bruteArr)
          .limit(maxParts)
          .collect(Collectors.toList())
          .toArray(new String[maxParts]);
    return ret;
  }

  public static String[] bruteSplit(String name, int maxLen) {
    List<String> res = new ArrayList<>();
    int start =0;
    int end = maxLen;
    while (end <= name.length()) {
      String substr = name.substring(start, end);
      res.add(substr);
      start = end;
      end +=maxLen;
    }
    String substr = name.substring(start, name.length());
    res.add(substr);
    return res.toArray(new String[res.size()]);
  }

  public static String[] spaceSplit(String str, int maxLen, int maxParts) {
    List<Integer> spaceIndexes = findSplitPoints(str, ' ');
    List<Integer> goodSplitIndexes = new ArrayList<>();
    int goodIndex = -1; 
    int curPartMax = maxLen;
    for (int i=0; i< spaceIndexes.size(); i++) {
      int idx = spaceIndexes.get(i);
      if (idx < curPartMax) {
        goodIndex = idx;
      } else {
        goodSplitIndexes.add(goodIndex+1);
        curPartMax = goodIndex+1+maxLen;
      }
    }
    if (goodSplitIndexes.get(goodSplitIndexes.size()-1) != str.length()) {
      goodSplitIndexes.add(str.length());
    }
    if (goodSplitIndexes.size()<=maxParts) {
      List<String> res = new ArrayList<>();
      int start = 0;
      for (int i=0; i<goodSplitIndexes.size(); i++) {
        int end = goodSplitIndexes.get(i);
        if (end-start > maxLen) {
          return null;
        }
        res.add(str.substring(start, end));
        start = end;
      }
      return res.toArray(new String[res.size()]);
    }
    return null;
  }


  private static List<Integer> findSplitPoints(String str, char c) {
    List<Integer> list = new ArrayList<Integer>();
    for (int i = 0; i < str.length(); i++) {
      if (str.charAt(i) == c) {
        list.add(i);
      }
    }
    list.add(str.length());
    return list;
  }
}

Basit test kodu:

  public static void main(String[] args) {
    String [] testStrings = {
        "123",
        "123 123 123 1123 123 123 123 123 123 123",
        "123 54123 5123 513 54w567 3567 e56 73w45 63 567356 735687 4678 4678 u4678 u4678 56rt64w5 6546345",
        "1345678934576235784620957029356723578946",
        "12764444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444444",
        "3463356 35673567567 3567 35 3567 35 675 653 673567 777777777777777777777777777777777777777777777777777777777777777777"
    };

    int max = 35;
    int maxparts = 2;


    for (String str : testStrings) {
      System.out.println("TEST\n    |"+str+"|");
      printSplitDetails(max, maxparts);
      String[] res = smartSplitToShorterStrings(str, max, maxparts);
      for (int i=0; i< res.length;i++) {
        System.out.println("  "+i+": "+res[i]);
      }
      System.out.println("===========================================================================================================================================================");
    }

  }

  static void printSplitDetails(int max, int maxparts) {
    System.out.print("  X: ");
    for (int i=0; i<max*maxparts; i++) {
      if (i%max == 0) {
        System.out.print("|");
      } else {
        System.out.print("-");
      }
    }
    System.out.println();
  }

0
2018-03-30 08:17