求职面试测试 - 查找字符串中出现的两个字符中第一个字符的索引

Job interview test - finding the index of the first of two chars to appear in a string

我刚刚参加了在线面试,被问到一个简洁的问题。我想我会与社区分享它,连同我的答案。看看您是否认为我的回答是正确的,如果不正确 - 您将如何改进它?我认为这可以使任何像我这样编码经验相对较短并试图迈出第一步的人受益。

注意 - 问题在正文中没有解释 - 必须自己弄清楚功能。该函数的作用是 return 给定 String schar achar b 的第一个实例,如果未找到则为 -1。

问题

尽可能简化下面的实现。 如果您还可以在简化过程中提高性能,那就更好了! 仅供参考:此代码超过 35 行和超过 300 个标记,但它可以写成 5 行,不到 60 个标记。

static int func(String s, char a, char b)
{
    if (s.isEmpty()) return -1;

    char[] strArray = s.toCharArray();

    int i=0;
    int aIndex=-1;
    int bIndex=-1;
    while (aIndex==-1 && bIndex==-1 && i<strArray.length)
    {
        if (strArray[i] == a)
            aIndex=i;
        if (strArray[i] == b)
            bIndex=i;
        i++;
    }


    if (aIndex != -1)
    {
        if (bIndex == -1)
            return aIndex;
        else
            return Math.min(aIndex, bIndex);
    }
    else
    {
        if (bIndex != -1)
            return bIndex;
        else
            return -1;
    }
}

我的回答:

static int func(String s, char a, char b)
{
    if (s.indexOf(a) != s.indexOf(b)) 
        return Math.min(s.indexOf(a), s.indexOf(b));
    else if (s.indexOf(a) == s.indexOf(b))
        return s.indexOf(a);
}

//returning Min(a,b) is redundant. it will always be -1

@Amos Bordowitz 的回答有效,我想我也是。

static int func(String s, char a, char b)
{
    return Math.max(s.indexOf(a), s.indexOf(b));
}

我为什么要关心 s.indexOf(a) == s.indexOf(b)Max() 即使它们相同,也始终有效。

下面的代码不如发布的解决方案简洁,但我相信它更快。我看到的其他解决方案对字符串进行两次迭代:O(2n)。下面的代码迭代字符串一次 O(n).

尽管在实践中,这应该无关紧要,我会选择其他(更清晰的)解决方案。

static int func(String s, char a, char b){
      if(s.length<=0){
            return -1;
      }else{
            char c = s.charAt(0);
            if((c==a)||(c==b)){
                 return 0;
            }else{
                int r = func(s.substring(1), a, b);
                return r<0?-1:r+1;
            }
     }
 }

分析

给定的代码是这样工作的:

  • 检查字符串是否为空 => return -1
  • while 循环在以下情况下停止:
    • 找到 char a 的索引
    • 找到 char b 的索引
    • 找到两个索引
    • 索引大于给定的字符串
  • 存在三个可能的 return 值
    • 如果找到 a(或 a 和 b)=> return aIndex
    • 如果找到 b => return bIndex
    • 如果没有找到 => return -1

解决方案

没有人想到最简单但在我看来最快的解决方案。其他每个人都调用 indexOf 两次,因此在字符串上迭代两次。

public int func(String s, char a, char b) {
  for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    if (c == a || c == b) {
      return i;
    }
  }
  return -1;
}

基准测试结果

设置

char 'x''z' 完全位于 String 的中间。测试字符串包含 10000 个字符。

import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Threads(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

  String s = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. \r\n"
      + "\r\n"
      + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. \r\n"
      + "\r\n"
      + "Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis. \r\n"
      + "\r\n"
      + "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, At accusam aliquyam diam diam dolore dolores duo eirmod eos erat, et nonumy sed tempor et et invidunt justo labore Stet clita ea et gubergren, kasd magna no rebum. sanctus sea sed takimata ut vero voluptua. est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat. \r\n"
      + "\r\n"
      + "Consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \r\n"
      + "\r\n"
      + "Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. \r\n"
      + "\r\n"
      + "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi. \r\n"
      + "\r\n"
      + "Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. \r\n"
      + "\r\n" + "Duis au";

  char a = 'x';
  char b = 'z';

  @Benchmark
  public int testLong() {
    if (s.isEmpty()) {
      return -1;
    }

    char[] strArray = s.toCharArray();

    int i = 0;
    int aIndex = -1;
    int bIndex = -1;
    while (aIndex == -1 && bIndex == -1 && i < strArray.length) {
      if (strArray[i] == a) {
        aIndex = i;
      }
      if (strArray[i] == b) {
        bIndex = i;
      }
      i++;
    }

    if (aIndex != -1) {
      if (bIndex == -1) {
        return aIndex;
      } else {
        return Math.min(aIndex, bIndex);
      }
    } else {
      if (bIndex != -1) {
        return bIndex;
      } else {
        return -1;
      }
    }
  }

  @Benchmark
  public int testIndexOf1() {
    return Math.max(s.indexOf(a), s.indexOf(b));
  }

  @Benchmark
  public int testSubstring() {
    return func(s, a, b);
  }

  private int func(String s, char a, char b) {
    if (s.length() <= 0) {
      return -1;
    } else if (s.charAt(0) == a || s.charAt(0) == b) {
      return 0;
    } else {
      int r = func(s.substring(1), a, b);
      return r < 0 ? -1 : r + 1;
    }
  }

  @Benchmark
  public int testLoop() {
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (c == a || c == b) {
        return i;
      }
    }
    return -1;
  }
}

结果

Benchmark                  Mode  Cnt        Score        Error  Units
MyBenchmark.testIndexOf1   avgt   30      949,729 ±     14,753  ns/op
MyBenchmark.testLong       avgt   30     4044,216 ±    122,244  ns/op
MyBenchmark.testLoop       avgt   30      725,502 ±     38,688  ns/op
MyBenchmark.testSubstring  avgt   30  3549335,410 ± 133681,449  ns/op

如果你想缩短代码,我想这就是你想要的

static int func(String s, char a, char b)
{
    if (s.isEmpty()) return -1;
    int n1=s.indexOf(a);
    int n2=s.indexOf(b);

    return (n1>n2?(n2>-1?n2:n1):(n1>-1?n1:n2));
 }