【问题标题】:Parsing and replacing doubles in Java String解析和替换 Java String 中的双精度数
【发布时间】:2015-10-10 12:38:59
【问题描述】:

我正在编写用于转换信号的 java 代码。如果给定的字符串(INPUT)是:

C*12.387a0d14assc7*18.65d142a

它的翻译(输出)应该是:

C*12387:1000a0d14assc7*1865:100d142a 

算法:

在字符串中的任何地方,一个星号(*)跟在一个包含小数的数字之后(在这个字符串中有两个,第一个是'*12.387',第二个是*18.65'),这个数字要变成分数,如上例 12.387 转换为 12387:1000 和 18.65 转换为 1865:100

如果十进制数是孤立的,我可以使用以下代码将其转换为分数:

    double d = 12.387;
    String str = Double.toString(d);        
    String[] fraction = str.split("\\.");

    int denominator = (int)Math.pow(10, fraction[1].length());
    int numerator = Integer.parseInt(fraction[0] + "" + fraction[1]);

    System.out.println(numerator + ":" + denominator);

但我不知道如何将十进制数的子字符串与其包含的字符串分开。作为 Java 和编程新手,我需要帮助。感谢期待。

【问题讨论】:

    标签: java regex parsing double substring


    【解决方案1】:

    使用正则表达式和捕获组是实现解析的好方法:

    String s = "C*12.387a0d14assc7*18.65d142a";
    StringBuffer result = new StringBuffer();
    Matcher m = Pattern.compile("\\*(\\d+)\\.(\\d+)").matcher(s);
    while (m.find()) {
        String num = m.group(1);
        String denom = m.group(2);
        String divisor = "1" + new String(new char[denom.length()]).replace("\0", "0");
        String replacement = "*" + num + denom + ":" + divisor;
        m.appendReplacement(result, replacement);
    }
    m.appendTail(result);
    System.out.println(result.toString());
    

    【讨论】:

    • 请注意它需要 StringUtils 外部库
    • 请参阅stackoverflow.com/a/4903603/1737819 以了解重复字符串。没有外部库:)
    • 替换的外部库
    • 此代码的输出非常震撼:C * 12387:1C * 12.387A0D14ASSC7 * 18.65D142AC * 12.387A0D14ASC7 * 18.65D142AC * 12.387A0D14ASC7 * 18.65D142AA0D14ASSC7 * 1865:1C * 12.387A0D14ASC7 * 18.65D14AC *12.387a0d14assc7*18.65d142ad142a
    • 抱歉,删除外部库依赖项时出现复制粘贴错误。现已修复...
    【解决方案2】:

    我正在编写一个使用正则表达式的解决方案,但随后尝试不使用它们。这里的解决方案是通用的(适用于任何编程语言)。当然,看看它是否比基于正则表达式的解决方案更快会很有趣。无论如何,我怀疑基于正则表达式的解决方案可能会更快。请也查看此解决方案(虽然它并不完美:))。

    import java.util.*;    
    
    class DoubleConvert 
    {
        public static void main (String[] args)
        {
            StringBuilder buffer = new StringBuilder("C*12.387a0d14assc7*18.65d142a");
            int j, m, k; 
            int i = 0;
            while (i < buffer.length())
            {
                if (buffer.charAt(i) == '*')
                {
                    m = -1; k = -1;
                    j = i; //remember where * found
                    while ( i + 1 < buffer.length() )
                    {
                        i++;
                        if (Character.isDigit(buffer.charAt(i)))
                        {
                            continue;
                        }
                        else if (buffer.charAt(i) == '.')
                        {
                            m = i; // remember where . found
                            while (i + 1 < buffer.length())
                            {
                                i++;
                                if (Character.isDigit(buffer.charAt(i)))
                                {
                                    continue;
                                }
                                else
                                {
                                    k = i; //remember the last position
                                    break;
                                }
                            }
                        }
                        else //let's see what we got
                        {
                            if (m > 0 && j > 0 && m - j > 0 && k - m > 0) //there must exist strings
                            {
                                System.out.println("Found " + buffer.substring(j, m) 
                                + " second part " + buffer.substring(m, k));
                                buffer.replace(j+1, k, 
                                        buffer.substring(j+1, m) + 
                                        buffer.substring(m+1, k) +
                                        ":1" +
                                        new String(new char[k-1-m]).replace("\0","0"));
                            }
                            break;
                        }
                    }
                }
                else 
                {
                    i++;
                }
            }
            System.out.println("Result " + buffer);
        }
    }
    

    输出

    Found *12 second part .387
    Found *18 second part .65
    Result C*12387:1000a0d14assc7*1865:100d142a
    

    【讨论】:

    • 你的这段代码很有竞争力。它很有教育意义,在所有伟大的书中都没有,它解决了我许多其他类似的问题。它给了我洞察力和创新能力。
    猜你喜欢
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2012-10-21
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多