Yanıtlar:
Bu -1
, Peter Lawrey'nin çözümünün sahip olduğu en sonunda pozisyonların listesini yazdırmalıdır .
int index = word.indexOf(guess);
while (index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index + 1);
}
Bir for
döngü olarak da yapılabilir :
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 olabiliyorsa, guess
dizeyi analiz ederek word
, yukarıdaki döngülerin yaptığından daha hızlı döngü yapmak mümkündür. Böyle bir yaklaşımın ölçütü Boyer-Moore algoritmasıdır . Ancak, böyle bir yaklaşımı kullanmayı tercih edecek koşullar mevcut görünmüyor.]
Aşağıdakini deneyin (Şimdi sonunda -1 yazmaz!)
int index = word.indexOf(guess);
while(index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index+1);
}
indexOf
karakter bulunamadığında -1 döndürür.
-1
Sonunda yazdırmasının nedeni , do
döngünün gövdeyi yürütmesi ve ardından bunu index == -1
sonlandırmada keşfetmesidir while
.
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();
Java9 ile iterate(int seed, IntPredicate hasNext,IntUnaryOperator next)
aşağıdakilerden yararlanılabilir: -
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);
Bu, Java 9 ile düzenli ifade kullanılarak işlevsel bir şekilde yapılabilir:
Pattern.compile(Pattern.quote(guess)) // sanitize input and create pattern
.matcher(word) // create matcher
.results() // get the MatchResults, Java 9 method
.map(MatchResult::start) // get the first index
.collect(Collectors.toList()) // collect found indices into a list
);
CharSequence
Uzantı yöntemini kullanarak bu mantığı API'ye yeni bir yöntem olarak eklemek için Kotlin Çözümü :
// Extension method
fun CharSequence.indicesOf(input: String): List<Int> =
Regex(Pattern.quote(input)) // build regex
.findAll(this) // get the matches
.map { it.range.first } // get the index
.toCollection(mutableListOf()) // collect the result as list
// call the methods as
"Banana".indicesOf("a") // [1, 3, 5]
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);
}
word.substring(word)
derlenmeyecek. : P
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);
Ayrıca, bir String'in tüm dizinlerini bulmak istiyorsanız.
int index = word.indexOf(guess);
while (index >= 0) {
System.out.println(index);
index = word.indexOf(guess, index + guess.length());
}
guess
oldu "aba"
ve word
oldu "ababa"
, eğer net değil guess
bir veya iki kez meydana gelir word
. (Demek istediğim, birinin guess
iki farklı konumdan başlayarak bulabileceği açıktır , ancak olaylar örtüştüğü için ikisinin de sayılması gerekip gerekmediği açık değildir.) Bu yanıt, örtüşen olayların ayrı olarak sayılmadığı görüşünü alır. Elbette, OP'nin ifadesi guess
her zaman 1 uzunluğa sahip olacağını kuvvetle önerdiğinden , belirsizlik ortaya çıkmaz.
Bu yöntemi bulana kadar ben de bu problemi yaşadım.
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 dizedeki herhangi bir uzunluktaki herhangi bir bayrağın 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);
}
}
Bulduğum dizeleri bölmek için bir sınıf. Sonunda kısa bir test sağlanır.
SplitStringUtils.smartSplitToShorterStrings(String str, int maxLen, int maxParts)
mümkünse sözcükleri bölmeden boşluklara bölünecek ve yoksa maxLen'e göre dizinlere bölünecektir.
Nasıl bölündüğünü 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();
}
Bu bir java 8 çözümüdür.
public int[] solution (String s, String subString){
int initialIndex = s.indexOf(subString);
List<Integer> indexList = new ArrayList<>();
while (initialIndex >=0){
indexList.add(initialIndex);
initialIndex = s.indexOf(subString, initialIndex+1);
}
int [] intA = indexList.stream().mapToInt(i->i).toArray();
return intA;
}
Bu, aşağıdaki parametreyi yineleyerek myString
ve kaydırarak yapılabilir :fromIndex
indexOf()
int currentIndex = 0;
while (
myString.indexOf(
mySubstring,
currentIndex) >= 0) {
System.out.println(currentIndex);
currentIndex++;
}
mySubstring
bulunup mySubstring
bulunamayacağına bakılmaksızın , son oluşum indeksine kadar her pozisyonu (0, 1, 2, ...) yazdıracaktır . OP'nin istediği hiç de değil ..
Bunu dene
String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(StringUtils.countMatches(str, findStr));