разобрать неотрицательные двойники - PullRequest
1 голос
/ 30 августа 2010

Мне нужна функция, которая будет принимать строку и целое число, указывающее позицию неотрицательного двойного или целого числа и возвращать число или ноль. Если есть «+», вернуть ноль.

Примеры

2.1      , 0 -> 2.1
+2.1     , 0 -> null
-1       , 0 -> null
-1.2     , 1 -> 1.2
qwa56sdf , 3 -> 56

Какой самый элегантный способ сделать это? Спасибо.

обн Мне нужен такой код, но лучше)

    Number parse(String str, int pos){
        Matcher m = Pattern.compile("^(\\d+(?:\\.\\d+)?)").matcher(str);
        m.region(pos, str.length());
        if(m.find()){
            return Double.parseDouble(m.group());
        } else {
            return null;
        }
    }

Ответы [ 6 ]

3 голосов
/ 30 августа 2010

Вы можете попробовать:

public static void main(String[] args) {
  System.out.println(parse("2.1", 0));
  System.out.println(parse("+2.1", 0));
  System.out.println(parse("-1", 0));
  System.out.println(parse("-1.2", 1));
  System.out.println(parse("qwa56sdf", 3));
}

private static Double parse(String string, int index) {
  if (string.charAt(index) == '-' || string.charAt(index) == '+') {
    return null;
  }
  try {
    return Double.parseDouble(string.substring(index).replaceAll("[^\\d.]", ""));
  }
  catch (NumberFormatException e) {
    return null;
  }
}

Мне пришлось убрать концевые нецифровые символы с помощью replace all, поскольку они вызывали исключение NumberFormatException и возвращали значение null для входных данных, подобных тому, который был в вашем последнем примере.

Редактировать: другой вариант работы для случаев, подобных тому, что в комментарии, может состоять в проверке каждого символа

private static Double parse(String string, int index) {
    String finalString = "";
    boolean foundSeparator = false;
    for (char c : string.substring(index).toCharArray()) {
        if (c == '.') {
            if (foundSeparator) {
                break;
            }
            else {
                foundSeparator = true;
            }
        }
        else if (!Character.isDigit(c)) {
            break;
        }
        finalString += c;
    }
    if (finalString == "") {
        return null;
    }
    return Double.parseDouble(finalString);
}
2 голосов
/ 30 августа 2010

Вам понадобится комбинация метода String.substring(), чтобы начать с указанной позиции в строке, и класса NumberFormat, чтобы проанализировать число.

1 голос
/ 27 ноября 2011

Я думаю, что следующая реализация будет более элегантной для вашего набора требований. Я использую класс java.text.NumberFormat для анализа.

    private static Number parse(String text, int position){
        Number value=null;
        NumberFormat nf = NumberFormat.getInstance();
        try {
            value = nf.parse(text,new ParsePosition(position));
            if (value.intValue() < 0)
                value = null;
        } catch (Exception e) {
            value = null;
        }
        return value;
   }
1 голос
/ 30 августа 2010
public static Double parseDouble(String input, int fromIndex) {
    Matcher matcher = Pattern.compile("\\d*\\.?\\d+")
        .matcher(input.substring(fromIndex));
    return matcher.lookingAt() ? Double.parseDouble(matcher.group()) : null;
}
1 голос
/ 30 августа 2010

Существует также класс Сканер . Который специально имеет методы для чтения в примитивах, например scanner.hasNextDouble() и scanner.nextDouble(). Вам все равно придется выполнить проверку на + или -, потому что это все равно пройдет проверку.

1 голос
/ 30 августа 2010

Если это функционально правильно, для меня это выглядит достаточно элегантно. Возможно, вы захотите сделать Pattern финальным членом класса, поскольку вам нужно скомпилировать его только один раз. И регион, вероятно, не нужен:

Matcher m = pattern.matcher(str.substring(pos));

Другой вариант - начать с подстроки длиной 1 символ и увеличивать ее до тех пор, пока она не перестанет анализировать:

if ( str.charAt(pos) == '+' || str.charAt(pos) == '-' ) {
    //special cases
    return null;
}
Double val = null;
for ( int i = pos+1; i <= str.length(); i++ ) {
    try {
       val = Double.parseDouble(str.substring(pos, i)) {
    }  catch (NumberFormatException e) {
       break;
    }
}
return val;

Это немного проще, но и наивно с точки зрения производительности. Менее читаемым, но более производительным решением было бы найти конец двойника самостоятельно, прежде чем приступить к анализу, просто посмотрев на символы по одному.

...