Получает индекс первой строки, которая начинается с цели — выдавать неверный результат

Вопрос:

Этот метод должен возвращать индекс первой строки, которая начинается с цели.

Верните -1, если строка не начинается с цели.

Мои реализации работают, но не охватывают все варианты.

Код:

public int getIndex(ArrayList<String> text, String target)
{
int i = 0;
int index = -1;
boolean found = false;

while (!found && i < text.size()) //supply condition
{
for (String s : text) {
if (s.contains(target)) {
found = true;
} else {
i++;
}

if (found) index = i;
}
}

return index;
}

часть тестирования:

public static void main(String[] args)
{
ArrayList<String> cities = new ArrayList<String>();
cities.add("Chicago");
cities.add("Houston");
cities.add("San Jose");
cities.add("Seattle");
cities.add("Denver");

Finder finder = new Finder();

System.out.println(finder.getIndex(cities, "C"));
System.out.println("Expected: 0");

System.out.println(finder.getIndex(cities, "S"));
System.out.println("Expected: 2");

System.out.println(finder.getIndex(cities, "D"));
System.out.println("Expected: 4");

System.out.println(finder.getIndex(cities, "X"));
System.out.println("Expected: -1");
}

Этот код имеет покрытие 50/50 :

  4
- Expected: 0
3
- Expected: 2
4
+ Expected: 4
-1
+ Expected: -1

Как решить эту проблему?

Лучший ответ:

Вы утверждаете:

Мои реализации

Это не похоже на меня, основываясь на тестах. Ваш код намного сложнее, чем нужно, что затрудняет поиск ошибки. Проблема в том, что у вас есть две циклы без причины:

while (!found && i < text.size()) //supply condition
{           
    for (String s : text) {
    }
}

Почему у вас есть оба этих цикла? Вы увеличиваете i несколько раз во внутреннем цикле…

Вероятно, вам будет легче пройти все тесты, если вы упростите это:

public int getIndex(List<String> text, String target) {
    for (int i = 0; i < text.size(); i++) {
        if (text.get(i).startsWith(target)) {
            return i;
        }
    }
    return -1;
}

Это один из тех случаев, когда догматическая настойчивость только в том, что имеет один оператор return на один метод, приводит к значительному более беспорядочному коду.

Обратите внимание, что я изменил условие из contains (в вашем коде) на startsWith чтобы соответствовать описанию. Вы должны добавить тест для этой разницы — попробуйте найти строку, которая присутствует в одном из городов, но город не начинается с этого значения.

Я также изменил тип параметра на List<String> как вам действительно не нужен ArrayList<String>. (С небольшой работой вы могли бы заставить его принять Iterable<String> вместо этого, но это было бы более сложно).

Я также рекомендую вам начать использовать JUnit или что-то подобное для вашего тестирования, а не просто использовать System.out.println.

EDIT: просто для удовольствия, версия, которая принимает Iterable<String> и использует ее для эффективного управления LinkedList<String>:

public int getIndex(Iterable<String> elements, String target) {
    int index = 0;
    for (String element : elements) {
        if (element.startsWith(target)) {
            return index;
        }
        index++;
    }
    return -1;
}

(В конце концов, это не так уж сложно…)

Ответ №1
public int getIndex(ArrayList<String> text, String target)
{

for(int i=0;i < text.size();i++)
{
if(text.get(i).indexOf(target) == 0)
return i;
}

return -1;
}
Ответ №2

Внесите следующие изменения:

  • Избавиться от ненужной found переменной
  • Заменить contains с startsWith
  • Удалите for -loop, иначе вы будете проходить через данные несколько раз
  • Измените while -loop на значение for -loop

Я добираюсь до этого, что, кажется, работает:

public int getIndex(ArrayList<String> text, String target)
{
int index = -1;

for (int i = 0; index == -1 && i < text.size(); i++)
{
if (text.get(i).startsWith(target))
{
index = i;
}
}

return index;
}

Конечно, вы можете улучшить его еще больше.

Ответ №3

Измените метод getIndex следующим образом:

public int getIndex(ArrayList<String> text, String target)
{
int i = 0;

for (String s : text) {
// Use startsWith if you want to check if the string starts with target...
// Use contains if you want to check if contains target...
if (s.startsWith(target)) {
return i;
}

i++;
}

return -1;
}

Оцените статью
TechArks.Ru
Добавить комментарий