【问题标题】:Given a string find the first embedded occurrence of an integer给定一个字符串,找到第一个嵌入的整数
【发布时间】:2012-04-02 07:34:36
【问题描述】:

这是在采访中被问到的:

给定任何字符串,告诉我第一次出现的整数。

例如

Str98 那么它应该返回 98

Str87uyuy232 -- 它应该返回 87

我通过字符串循环给出答案,并将其与数字字符进行比较,如

if ((c >= '0') && (c <= '9'))

然后我得到了数字的索引,解析它并返回它。不知怎的,他并不相信。 任何人都可以分享最好的解决方案吗?

【问题讨论】:

  • 他/她可能正在寻找答案的正则表达式版本
  • 您是否从遇到的第一个数字继续到最后一个连续数字?

标签: java


【解决方案1】:

这个解决方案有两个问题。

  1. 考虑测试用例 - 有 2 个字符“8”和“7”,它们都构成了您应该返回的整数 87。 (这是主要问题)

  2. 这有点迂腐,但字符“0”的整数值不一定小于“1”、“2”等的值。可能几乎总是如此,但我想面试官喜欢看到这种关怀。更好的解决方案是

    if (Character.isDigit(c)) { ... }

有很多不同的方法可以做到这一点。我的第一个想法是:

int i = 0;
while (i < string.length() && !Character.isDigit(string.charAt(i))) i++;
int j = i;
while (j < string.length() && Character.isDigit(string.charAt(j))) j++;
return Integer.parseInt(string.substring(i, j)); // might be an off-by-1 here

当然,正如 cmets 中所述,在 Java 中使用正则表达式功能可能是最好的方法。但是当然很多面试官会要求你在没有库等的情况下做这样的事情......

【讨论】:

  • 至于你的数字 2,我相信 0 的字符值总是小于 1,它遵循 ASCII 值:staffweb.londonmet.ac.uk/~chalkp/java/sbu/book/appa/appa4.htm
  • 在 ASCII 中这当然是正确的,但如果系统不使用 ASCII 怎么办? Java(我在这里使用)可能会处理它,但系统可能没有使用 ASCII - 正如我所说:pedantic
  • @mfrankli - 这个问题被标记为java,但我同意。不同的编码可能定义不同。
  • 但是这个问题被标记为Java,所以java对于这个问题很重要。在 itnerview 中提到使用 Unicode 的系统(在 Unicode 中 0 仍然小于 1),这将是一件重要的事情。但是对于java来说,做OP做的比较还是有效的。此外,使用 Character.isDigit 可能会引入开销,这使得 OP 的方法成为更好的解决方案。
  • @Danny - 在可维护性方面,RegEx 解决方案需要维护的代码要少得多,尤其是对于像这样的简单情况。一般而言,RegEx 在编译模式时受到的影响最大,而在实际解析时受到的影响较小。因为我是一个的粉丝,我喜欢使用更简单(即更容易维护)的代码,直到我可以证明我从中获得了所需的速度提升(即使用分析器),并且可以获得通过改变它来获得足够大的速度提升。
【解决方案2】:

使用正则表达式非常简单:

String s = new String("Str87uyuy232");
Matcher matcher = Pattern.compile("\\d+").matcher(s);
matcher.find();
int i = Integer.valueOf(matcher.group());

(Thanks to Eric Mariacher)

【讨论】:

  • Matcher matcher = Pattern.compile("\\d+").matcher(s);以上是做什么的??
  • \` escapes the ` 以便正则表达式拾取它。 \d 匹配一个“数字”(0-9)。 “+”表示“1 或更多”。 .matcher(s) 通过编译模式运行字符串,为您提供一个 Matcher,然后您可以使用它进行操作,例如 .find(),它将自身设置为匹配的第一个实例。
  • @harigm 我不同意这是面试问题的最佳答案。像这样的问题往往是算法/数据结构问题,你应该使用算法。那么当面试官问“这个解决方案的性能如何”时呢?除非您非常熟悉 Java 的实现,否则您无法真正使用正则表达式解决方案给出答案。在这种情况下,将字符串分解为数组并循环似乎确实是正确的答案。然后,您可以解释如何在 O(n) 时间内执行它,并展示对字符串和数组的理解。
  • @StefanH - 我同意能够谈论基本数据结构和算法复杂性在面试中很重要,但我也想知道候选人理解适用于语言的可用工具这样的问题。此外,讨论可维护性和优缺点也很重要。理想情况下,我希望看到 两种 解决方案(正则表达式和非正则表达式)从理想的候选人中脱颖而出,并对这两种方法进行了很好的讨论。 (自我注意:将其归档以备将来使用)
  • new String 是怎么回事?
【解决方案3】:
String input = "Str87uyuy232";
Matcher m = Pattern.compile("[^0-9]*([0-9]+).*").matcher(input);
if (m.matches()) {
    System.out.println(m.group(1));
}

【讨论】:

  • 对我很好。一个干净的解决方案,简洁并检查不匹配......我认为这是一个关键细节
【解决方案4】:

以防万一您想要非正则表达式而不使用其他实用程序。

给你

public static Integer returnInteger(String s)
{
    if(s== null)
        return null;
    else
    {
        char[] characters = s.toCharArray();
        Integer value = null;
        boolean isPrevDigit = false;
        for(int i =0;i<characters.length;i++)
        {
            if(isPrevDigit == false)
            {
                if(Character.isDigit(characters[i]))
                {
                    isPrevDigit = true;
                    value = Character.getNumericValue(characters[i]);
                }
            }
            else
            {
                if(Character.isDigit(characters[i]))
                {   
                    value = (value*10)+ Character.getNumericValue(characters[i]);
                }
                else
                {
                    break;
                }
            }
        }
        return value;
    }
}

【讨论】:

  • 如果字符串是“myString 000”怎么办?您将无法从实际上具有 int 0 的字符串中识别空字符串
  • @StefanH int 不能为空,但如果你真的想要,那么用对象类包装它。
  • 对不起,你误解了我的意思。使用您提供的代码,您无法区分输入字符串为 null 和 0 是字符串中的第一个整数。
【解决方案5】:

你也可以去一个较低的级别。快速查看ASCII values 会发现字母字符从 65 开始。数字从 48 到 57。在这种情况下,您可以简单地对 127 使用“和”n 字符,看看该值是否满足阈值 48 - 57 .

    char[] s = "Str87uyuy232".toCharArray();
    String fint = "";
    Boolean foundNum = false;

    for (int i = 0; i < s.length; i++)
    {
        int test = s[i] & 127;
        if (test < 58 && test > 47)
        {
            fint += s[i];
            foundNum = true;
        }
        else if (foundNum)
            break;
    }
    System.out.println(fint);

这样做对现实世界没有好处(不同的字符集),但作为一个谜题解决方案很有趣。

【讨论】:

    【解决方案6】:

    使用java.util.Scanner

    int res = new Scanner("Str87uyuy232").useDelimiter("\\D+").nextInt();
    

    Scanner 的目的是从输入中提取标记(这里是String)。标记是由分隔符分隔的字符序列。默认情况下,Scanner 的分隔符是空格,因此标记是空格分隔的单词。

    在这里,我使用分隔符\D+,意思是“任何不是数字的东西”。我们的Scanner 可以在我们的字符串中读取的标记是“87”和“232”。 nextInt() 方法会读取第一个。

    nextInt() 抛出 java.util.NoSuchElementException 如果没有要读取的令牌。在调用nextInt() 之前调用方法hasNextInt(),以检查是否有要阅读的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多