#java #string #loops #substring
#java #строка #циклы #подстрока
Вопрос:
Итак, вот чего я пытаюсь достичь. Я пытаюсь создать код, который выполняет следующее из 2 заданных строк: a target
и a source
.
// Determines whether the string TARGET occurs as a substring of string SOURCE where "gaps" are allowed between characters of target.`
// That is, the characters in TARGET occur in SOURCE in their given order but do not have to be adjacent.`
// (Pictured another way, this method returns true if TARGET could be obtained from SOURCE by removing some of the letters of SOURCE.)`
// This method is case sensitive. For example,`
// containsWithGaps("hamburgers", "mug") returns true`
// containsWithGaps("hamburgers", "burrs") returns true`
// containsWithGaps("hamburgers", "hamburgers") returns true`
// containsWithGaps("hamburgers", "gum") returns false`
// containsWithGaps("hamburgers", "hamm") returns false`
// containsWithGaps("hamburgers", "") returns true`
// Parameters:`
// SOURCE - the given string in which to find the target characters`
// TARGET - the characters to be found`
// Returns:`
// true if the characters in TARGET can be found as a subsequence in SOURCE, false otherwise`
И вот код, который я написал. Это кажется слишком сложным для того, что, по моему мнению, не должно быть сложной задачей, но, несмотря ни на что, я все равно продолжаю получать ошибки, и это не будет работать, если задана ИСХОДНАЯ строка hamburgers
с ЦЕЛЕВОЙ строкой burr
:
public static boolean substringWithGaps(String source, String target) {
boolean substring = false;
int[] target_index;
target_index = new int [target.length()];
if (target.length() > source.length()) {
substring = false;
}
else {
for (int i = 0; i < target.length(); i ) {
if (source.contains("" target.charAt(i))) {
target_index[i] = target.indexOf(i);
i ;
}
else {
target_index[i] = target.indexOf(i);
i ;
}
}
for (int i = 0; i < target_index.length; i ) {
if (target_index[i] == -1) {
substring = false;
break;
}
else if (target_index[i] >= target_index[i 1]) {
substring = false;
break;
}
else {
substring = true;
}
if (target_index.length != target.length()) {
substring = false;
}
}
}
return substring;
}
Есть идеи?
Комментарии:
1. Pseaudocode:
String foo = source.replace(/s /, "", g); if (-1 != foo.indexOf(target) { hooray() }
2. Именно это
source.contains(target)
в Java будет работать нормально.3. @Jorge Campos Нет, это не удовлетворит требованиям — оно вернет true, только если цель находится точно в источнике. Требование заключается в том, что могут быть промежуточные буквы,
Ответ №1:
Должно быть довольно просто:
public static boolean substringWithGaps(String source, String target) {
int targetIndex = 0;
for (int i = 0; i < source.length(); i ) {
if (source.charAt(i) == target.charAt(targetIndex)) {
targetIndex = targetIndex 1;
if (targetIndex == target.length()) {
return true;
}
}
}
return false;
}
Мы сохраняем указатель следующей буквы , которую нам нужно найти внутри target
. Затем мы перебираем source
поиск по этой букве, и когда мы находим ее, мы перемещаем индекс в пределах target
прямой единицы. Если индекс target
когда-либо равен длине target
, это означает, что мы нашли все нужные нам символы. Если мы перебираем весь исходный код, не находя всех target
, мы возвращаем false .
Комментарии:
1.
StringIndexOutOfBoundsException
когда target=»»2. Да, но это то, чего я, кажется, не понимаю. возьмите
source = "hamburger"
иtarget = "burr"
в строке 4 вашего кода, ` if (source.charAt(i) == target.charAt(targetIndex)) {` targetIndex останется равным 0, пока цикл не повторитсяb
hamburger
, чей индекс # равен 3, но targetIndex все равно должен быть равен 0, поэтому они никогда не будутравно.3. @saka1029 Я добавил в
if (target == ""){return true; }
начало, и, похоже, после этого все работает нормально4. Боже, я идиот. Хорошо, теперь я это понимаю, спасибо!
5. @Muldawg2020 Вы спрашиваете, почему
targetIndex
в этом коде значение остается равным 0.targetIndex
ссылается на индекс строкиtarget
. Таким образом, значениеtargetIndex
ДОЛЖНО быть равно 0 при поиске «b», в то время как индексуsource
разрешено перемещаться вперед. Загрузите код и запустите его самостоятельно, если считаете, что он не работает. Я уже протестировал это и получил правильные результаты.
Ответ №2:
Это должно быть сделано следующим образом.
public static boolean containsWithGaps(String a, String b){
if(b.length() > a.length())
{
return false;
}
char[] targetChars = new char[b.length()];
b.getChars(0,b.length(),targetChars, 0);
int pos = 0;
for(char myChar : targetChars)
{
pos = a.indexOf(myChar, pos);
if(pos == -1)
{
return false;
}
}
return true;
}
Ответ №3:
Небольшая оптимизация в том смысле, что она возвращается, как только символ не может быть сопоставлен (и не завершается сбоем, если цель имеет нулевую длину)
public static boolean substringWithGaps(String source, String target) {
for (int i = 0, last = -1; i < target.length(); i ) {
if (-1 == (last = source.indexOf(target.charAt(i), last 1)))
return false;
}
return true;
}