Соответствие шаблону несколько раз в строке - PullRequest
0 голосов
/ 29 апреля 2020

Цель состоит в том, чтобы заменить double типом функции распределения, то есть преобразовать строки, подобные этой

0.5 * x + 0.5 * y

, в строку типа:

IntPMF[(0;0.5)(1;0.5)] * x + IntPMF[(0;0.5)(1;0.5)] * y

Я написал следующее функция:

    public static String replaceDoubles(String stoEx) {
    Pattern p = Pattern.compile("(\\d+(?:\\.[0-9]\\d*))");
    Matcher m = p.matcher(stoEx);
    while (m.find()) {
        double d = Double.parseDouble(m.group(1));
        String dStr = String.valueOf(d);
        String[] parts = dStr.split("\\.");
        int lower = Integer.valueOf(parts[0]);
        int upper = lower + 1;
        double decimalPart = d - lower;
        decimalPart = round(decimalPart, 2);
        double rest = round(1 - decimalPart, 2);
        String replacement = "IntPMF[(" + lower + ";" + rest + ")(" + upper + ";" + decimalPart + ")]";
        stoEx = stoEx.replaceAll(m.group(1), replacement);
    }
    return stoEx;
}

Проблема в том, что с этой функцией я получаю следующий вывод (для вышеупомянутой строки):

IntPMF[(0;IntPMF[(0;0.5)(1;0.5)])(1;IntPMF[(0;0.5)(1;0.5)])] * x + IntPMF[(0;IntPMF[(0;0.5)(1;0.5)] (1;IntPMF[(0;0.5)(1;0.5)])] * y

Двойники 0,5 заменяются несколько раз ...

Буду признателен за любые предложения по решению. Спасибо!

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Если я правильно понимаю требования, вы можете использовать что-то вроде этого. Для округления значений и получения интерпретации рекомендуется использовать DecimalFormatter. Не используйте для этого внутренние библиотеки JDK.

public static void main( String[] args )
{
    DecimalFormat df = new DecimalFormat( "0.00" );

    //0.52 -> IntPMF[(0;0.48)(1;0.52)]
    String stoEx = "0.5 * x + 0.32222* y";
    Pattern p = Pattern.compile( "(\\d+\\.\\d+)" );
    Matcher m = p.matcher( stoEx );
    String result = "";
    StringJoiner stringJoiner = new StringJoiner( "+" );
    String[] splitString = stoEx.split( "\\+" );
    for( String subString: splitString )
    {
        if( m.find() )
        {
            String fracPart = m.group( 1 ).split( "\\." )[1];
            String fracOne = df.format( 1 - ( Integer.parseInt( fracPart ) / Math.pow( 10.0, fracPart.length() ) ) );
            String fracTwo = df.format( ( Integer.parseInt( fracPart ) / Math.pow( 10.0, fracPart.length() ) ) );
            String resultEx = "IntPMF[(" + 0 + ";" + fracOne + ")(" + 1 + ";" + fracTwo + ")]";
            result = subString.replaceFirst( m.group( 1 ), resultEx );
            stringJoiner.add( result );
        }
    }
    System.out.println( stringJoiner.toString() );
}
0 голосов
/ 06 мая 2020

Я пропустил часть вычислений, поскольку вы заинтересованы в замене открытого текста:

    final private static Pattern doublePattern = Pattern.compile("\\d+\\.\\d+");
    final private static String outputTemplate = "IntPMF[(0;%1$s)(1;%2$s)]";

    public static void main(String[] args) {
        String text = "0.5 * x + 0.32222* y";

        StringBuilder sb = new StringBuilder();

        int pos = 0;
        Matcher matcher = doublePattern.matcher(text);
        while(matcher.find()) {
            Double d = Double.parseDouble(matcher.group());
            String s1 = "s1"; // compute first parameter here
            String s2 = "s2"; // compute second parameter here

            // add part before matching
            sb.append(text.substring(pos, matcher.start()));
            pos = matcher.end();
            // add template
            sb.append(String.format(outputTemplate, s1, s2));
        }
        // add leftovers
        sb.append(text.substring(pos));

        System.out.println(sb);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...