获取以目标开头的第一个String的索引 - 给出错误的输出

时间:2013-07-05 15:09:42

标签: java algorithm match output

此方法应返回以目标开头的第一个字符串的索引。

如果没有字符串以目标开头,则返回-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

如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

你声称:

  

我的实施工作

根据测试结果,它看起来不像我。您的代码比它需要的复杂得多,这使得很难找到错误。问题是你无缘无故地得到了两个循环:

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

编辑:只是为了一点乐趣,这个版本需要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 :(得分: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 :(得分:1)

进行以下更改:

  • 摆脱不必要的found变量
  • contains替换为startsWith
  • 删除for - 循环,否则您会多次传递数据
  • while - 循环更改为for - 循环

我明白了,seems to work

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;
}

你当然可以improve on it a lot more still

答案 3 :(得分:0)

使用以下命令更改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;
}