Этот метод должен возвращать индекс первой строки, которая начинается с цели.
Верните -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;
}
(В конце концов, это не так уж сложно…)
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;
}
Внесите следующие изменения:
- Избавиться от ненужной
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;
}
Конечно, вы можете улучшить его еще больше.
Измените метод 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;
}