【问题标题】:How to implement trim() method in java by using only substring() method如何仅使用 substring() 方法在 java 中实现 trim() 方法
【发布时间】:2016-02-05 21:20:50
【问题描述】:

我知道这个问题很傻,但是在一次采访中我被告知要实现 trim() 方法,而不使用 String 类中的任何方法,除了 substring() 方法。

我通过使用 toCharArray() 然后识别字符串的第一个和最后一个有效字符来解决这个问题。但被告知不要使用 toCharArray() 方法。

任何人都可以提出一些方法来做到这一点。

允许重写 Objects 类的方法,例如 equals() 和 hashCode()。

【问题讨论】:

  • 使用String#equals(..) 算作String 类的方法吗?我认为它会,但我想检查 b/c 它是来自 Object 的覆盖方法
  • 提示:String.indexOf()
  • 这似乎是一个可怕的问题。我可以想出一种仅使用substringequals 来实现它的方法,但这将是一种可怕的方法。为什么要强迫某人编写糟糕的糟糕代码?
  • 你连length()都不能用吗?如果是这样的话,这是一个非常非常糟糕的面试问题。它基本上是在问,“你能设计出一些过于复杂和低效的东西,以至于没有人愿意维护它吗?”
  • 恕我直言,这不是一个糟糕的面试问题。虽然有人问,但这并非不可能。这只是为了测试一次答案和逻辑思维。将字符串读入某种字节缓冲区并找到空格,同时记住它们的位置,然后进行子串化似乎并非不可能。

标签: java string


【解决方案1】:
String untrimmed = "  some   string   ";
String trimmed = "";

String innerSpaces = "";
boolean wordBoundary = true;

try {
    for (int i = 0; ; i++) {
        String substr = untrimmed.substring(i, i + 1);

        if (!substr.equals(" ") && !substr.equals("\t") && 
               !substr.equals("\n") && !substr.equals("\r")) {

            trimmed += innerSpaces + substr;
            wordBoundary = false;
            innerSpaces = "";
        }
        else if (!wordBoundary) {
            innerSpaces += substr;
        }
    }
}
catch (IndexOutOfBoundsException e)  { }

System.out.println(trimmed);

【讨论】:

  • try-catch 太可怕了
  • 在不知道字符串长度的情况下,没有其他方法可以知道字符串何时结束。有什么建议吗?
  • 那是真的,但我认为他只是误解了这个问题。当然,他应该有权访问仅获取有关数组本身的底层 char 数组的一些信息的方法。但我明白你的意思......
  • 鉴于荒谬的初始条件,这也是我最终的结果。但是,这类面试问题会让我不接受这份工作。
  • trim 也会删除换行符。
【解决方案2】:

当然,修剪后的结果需要substring

如果没有String 的任何方法,将很难在两端找到可能的空格。

遗迹:

  1. 外部处理:

    某种形式

    Pattern pattern = Pattern.compile("\\s*(\\S*)\\s*"); // Pattern not okay
    Matcher m = pattern.matcher(string);
    string = m.matches()? m.group(1) : string;
    

    或者:

    Set<String> set0 = new HashSet<>();
    set0.add(string);
    Set<String> set = new HashSet<>();
    try {
        set.add(" " + string.substring(1));
        if (set0.contains(set)) {
            ...
    } catch (IndexOutOfRangeException e) { ... }
    
  2. 使用 String 超类的方法。然而,没有一个不被 String 本身覆盖。也许以下是允许的:

    CharSequence cs = string;
    // Use cs.charAt or Whatever
    

两者似乎都是合法的解决方案。 我很想知道他们的解决方案——或者这是一个不可能回答的问题。

【讨论】:

  • 这不是一个有效的答案。该问题明确指出,这种伪修剪方法需要使用substring 方法。虽然您的解决方案有效,但它不符合问题的要求。
  • 这是有效的 afaik。他说他只能使用子字符串,而不是需要它。
  • @MageXy 我读到这个问题的方式是,除了substring(),你不能使用任何方法。它并不是说你必须使用substring()。但如果他们坚持,我可以获取匹配组的开始和结束索引,并在原始字符串上调用 substring()。 :)
  • 这对于像[space]foo[space]bar[space] 这样的字符串将失败,因为模式将只接受[space]foo[space],这意味着matches() 将返回false,因此string 将是相同的。您可能想改用Pattern.compile("\\s*(\\S+(\\s+\\S+)*)\\s*");
  • @Pshemo 感谢您提供正确的模式。我后来也看到了错误,但是我不想在没有对面试官发表评论的情况下给出面试答案这样的解决方案。可能他们忘记允许equalsinternalize(所以可以使用==
【解决方案3】:

Hacky,但无论如何这个问题很愚蠢:

public static String trim(String s) {
    StringBuilder sb = new StringBuilder(s);
    int start, end;
    for (start = 0; start < sb.length() && Character.isWhitespace(sb.charAt(start)); start++);
    for (end = sb.length() - 1; end > start && Character.isWhitespace(sb.charAt(end)); end--);
    return sb.substring(start, end + 1);
}

System.out.println(trim("   \n \t trim me  \t "));

【讨论】:

  • 不错!真的很喜欢 1+
【解决方案4】:

您可以作弊并间接调用Strings 方法:

StringBuilder sb = new StringBuilder(sb);
for (int i = 0; i < sb.length(); i++) {
   char ch = sb.charAt(i);
   ...
}

如果有人问,你不会在 String 上调用任何方法,甚至不会在 substring() 上调用。 StringBuilder 为您服务。 :)

总而言之,这是一个可怕的问题,我不会担心。

【讨论】:

    【解决方案5】:

    一个非常低效的解决方案,但它就是这样。

    您在 cmets 中说过您可以使用 .equals() 方法。所以这是我精心设计的解决方案:

    你知道汽车里的里程表吗?那些去 0000, 0001, 0002... 等等?用 char arrayList 模拟它。

    从大小 1 开始,遍历每个字符,使用mainString.equals(charArrayList.toString()) 进行比较。如果您通过所有字符,但没有匹配,则将大小增加一并重复。匹配后,您可以检查开头和结尾的空白字符。

    请记住,我知道这效率不高,但它确实有效。即使需要一年:)

    希望这会有所帮助!

    【讨论】:

      【解决方案6】:

      如果您首先根据substring 重新定义length()charAt(),这并不难...奖金同时定义了length()charAt()

        public static int length(String s) {
          for(int i = 0; i < Integer.MAX_VALUE; i++) {
            try {
              s.substring(i);
            }catch(StringIndexOutOfBoundsException e) {
              return i - 1;
            }
          }
          return Integer.MAX_VALUE;
        }
      
        public static char charAt(String s, int idx) {
          String c = s.substring(idx, idx+1);
          return (char)c.hashCode();
        }
      
        public static String trim(String s) {
          final int length = length(s);
          int startIndex;
          int endIndex;
      
          for(startIndex = 0; startIndex < length; startIndex++) {
            char c = charAt(s, startIndex);
            if(! Character.isWhitespace(c)) {
              break;
            }
          }
      
          for(endIndex = length; endIndex > startIndex; endIndex--) {
            char c = charAt(s, endIndex - 1);
            if(! Character.isWhitespace(c)) {
              break;
            }
          }
          return s.substring(startIndex, endIndex);
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-16
        • 2012-09-02
        • 2018-02-14
        • 2020-07-15
        • 2014-02-06
        • 1970-01-01
        • 2014-01-13
        • 1970-01-01
        相关资源
        最近更新 更多