Метод работает только с параметрами <5000 args - PullRequest
0 голосов
/ 22 марта 2019

У меня небольшая проблема с методом преобразования строки типа «n.n +, n.n +, n.n +, ..., n.n +». в последовательности двойной. Все отлично работает, если у меня меньше, чем 4998 значений. Если у меня 4998 или больше, выдается следующее исключение:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1.178293466734042,"
        at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
        at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
        at java.base/java.lang.Double.parseDouble(Double.java:543)
        at java.base/java.lang.Double.valueOf(Double.java:506)

Вот метод, который я написал:

private static void parseDoubleArrayFromInput (String[] input, double[] parsedDoubles){
        for(int i = 0 ; i < input.length - 1; i++){                     //Removes the last character, which is the comma, apart from the last valid string.
            if(i == input.length - 2)                                   //Does not consider the last string of the array since it contains only the dot.
                parsedDoubles[i] = Double.parseDouble(input[i]);        //Then, it fills the array of doubles with the parsed double.
            else
                parsedDoubles[i] = Double.parseDouble(input[i].substring(0,input[i].length()-1));
        }
    }

Это класс, который генерирует файлы

import java.time.*;

public class PRNG {

    public PRNG(){

    }

    public static String generatePseudoRandomNumbers(double actual, int repetitions) {        //main function, generates pseudo random numbers and
        String output = "";
        double[] values = new double[repetitions];
        for(int i = 0; i < repetitions; i++) {
            double nextNumber = Math.pow(7,5)* actual % (Math.pow(2,31)- 1);    //algorithm to generate next pseudo random number
            actual = nextNumber;
            double singleResult = (2*(actual / (Math.pow(2,31) - 2))); //equation to shrink random numbers in a little range (0..100 in this case)
            output = output + singleResult + ", ";
        }
        output = output.substring(0, output.length()-3) + " .";
        return output;
    }

    public static int generatePseudoRandomNumbersTimes(double actual) {
        double nextNumber = Math.pow(7,5)* actual % (Math.pow(2,31)- 1);
        int singleResult = (int)(21*(nextNumber / (Math.pow(2,31) - 2)));
        return singleResult;
    }
}

И это класс, который должен получить входные данные и проанализировать их в последовательности двойных чисел

import java.util.Arrays;

public class StupidAlg {

    public static void main (String[] args){
        double[] doubleInput;
        if (args.length ==0) {
            System.out.print("");
        }
        else {
            doubleInput = new double[args.length - 1];
            parseDoubleArrayFromInput(args, doubleInput);
            double target = sum(doubleInput) / 2;                   //find target value
            double value = findWeightedMedian(doubleInput, target);
            System.out.print(value);
        }
    }

    private static void parseDoubleArrayFromInput (String[] input, double[] parsedDoubles){
        // process all of the input
        for(int i = 0 ; i < input.length - 1; i++) {
            // remove from the input things that will break the parsing
            // NOTE: other approaches could be used to ensure there is
            //   only a single ".".
            // NOTE: assumes the input to be US standard, as other approachs
            //        might use a "," for separator
            String clean = input[i].replaceAll("[^0-9.]", "");

            // put the result
            parsedDoubles[i] = Double.parseDouble(clean);
        }
    }

    private static double findWeightedMedian (double[] input, double target){
        Arrays.sort(input);
        double sum = 0;
        double result = 0;
        for(double v : input){
            sum += v;
            if (sum >= target) {
                result = v;
                break;
            }
        }
        return result;
    }

    private static double sum (double[] input){
        double result = 0;
        for(double v : input){
            result = result + v;     //sum all values in array
        }
        return result;
    }
}

Я использовал библиотечные массивы только потому, что не хотел реализовывать алгоритм сортировки, поскольку это простая проблема, и это тестовый файл.

Входные файлы сделаны таким образом

0.2931308777007562, 0.650659222761783, 1.6295518657467811, 1.8781948535500046, 0.8208889158637159, 0.680002497211101, 0.8019653053972547, 0.6308815354768946, 1.2259618232268485, 0.7403533791567696, 1.1192376940690332, 1.0279154591522324, 0.1751139268047306, 1.139766437131694, 0.05449995217332612, 1.9806957514776808, 1.5534795844494176, 1.3313636838750575, 0.22942446845530018, 1.937039533571377, 1.8234255749950423, 0.31362467102112684, 1.08984339804374, 0.9979823920856997, 1.090055974284239, 0.570751264291583 .

Ответы [ 2 ]

1 голос
/ 22 марта 2019

Обычно Array использует int для внутреннего использования, поэтому Integer.MAX_VALUE должен быть разрешен, но это также зависит от типа данных, который вы сохраняете в Array, от его размера и размера памяти, доступной для кучи.Возможно, это не тот ответ, который вы искали, но стоит попробовать.Вы можете найти детали здесь

1 голос
/ 22 марта 2019

Исключение довольно очевидно - Double.parseDouble() (на самом деле, все методы Integer / Long / etc. .parseXXX()) сгенерирует, если входная строка не в ожидаемом формате.

Итак, лучше всего:

  • Поймать исключение или знать, что оно может распространяться
  • Проверить правильность ввода перед попыткой анализа

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

private static void parseDoubleArrayFromInput (String[] input, double[] parsedDoubles){
    // process all of the input
    for(int i = 0 ; i < input.length; i++) {
        // remove from the input things that will break the parsing
        // NOTE: other approaches could be used to ensure there is 
        //   only a single ".".
        // NOTE: assumes the input to be US standard, as other approachs
        //        might use a "," for separator
        String clean = input[i].replaceAll("[^0-9.]", "");

        // put the result
        parsedDoubles[i] = Double.parseDouble(clean);
    }
}   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...