在j2se或Jakarta公共中有什么内容可以将数字转换为数字数组吗?

时间:2009-07-31 15:57:28

标签: java

我讨厌对现有的内容进行编码。我似乎无法在雅加达公共场所找到一种方法,如下所示:

long x= 12345;
int[] digits = toDigitsArray(x); //[1,2,3,4,5]

所以在我编写自己的toDigitsArray()方法之前,有没有人知道j2se或commons中是否存在等价物?

6 个答案:

答案 0 :(得分:4)

x.toString()。toCharArray()怎么样?结果将是一个字符数组,而不是你在示例中寻找的一组int,但你可以在使用时将字符转换为int,或者取决于你尝试用它做什么,chars可能没事。

答案 1 :(得分:2)

据我所知,目前还没有这样的功能。滚动你自己有一些值得讨论的陷阱。

我通过一些参数运行了三个选项(拆分字符串并进行模数运算并生成一个char数组),这是我能看到的最“有效”的选项。请注意一些假设:

  1. 我们必须支持Long
  2. 我们保留数字的符号位,但不在数组中。
  3. 首先是模数路线,乍一看应该是最有效的。但是,如果数字真的很长(超过int的最大值),那么mod运算符会溢出并产生垃圾结果。那么我们必须转向BigInteger(据我所知,如果有人看到更好的解决方案,请发表评论):

    public static void main(String[] args) {
        long x = 981212131233123L;
        int[] r = new int[calculateSize(x)];
        boolean positive = fillArrayWithDigits(x, r);
        //r = [9, 8, 1, 2, 1 ...
    }
    
        private static boolean fillArrayWithDigits(long y, int[] r) {
            boolean positive = y >= 0;
            y = Math.abs(y);
            BigInteger ten = BigInteger.valueOf(10);
            for (int i = r.length; i > 0; i--) {
                r[i-1] = BigInteger.valueOf(y).mod(ten).intValue();
                y /= 10L;
            }
            return positive;
        }
    
        private static int calculateSize(long y) {
            int size = 0;
            do {
                size++;
                y /= 10L;
            } while (y != 0);
            return size;
        }
    

    在这结束时,你有一个布尔值,表明数字是否为正,以及一个包含数字的数组。

    在进行字符串解析方面,我能想出的“最佳”是:

    public static void main(String[] args) {
        long x = 981212131233123L;
        boolean positive = x >= 0;
        x = Math.abs(x);
        String[] s = Long.toString(x).split("");
        int[] r = new int[s.length - 1];
        for (int i = r.length; i > 0; i--) {
            r[i-1] = Integer.parseInt(s[i]);
        }
        //r = [9, 8, 1, 2, 1 ...
    }
    

    char数组方法非常相似:

        public static void main(String[] args) {
            long x = 981212131233123L;
            boolean positive = x >= 0;
            x = Math.abs(x);
            char[] s = Long.toString(x).toCharArray();
            int[] r = new int[s.length];
            for (int i = r.length - 1; i > -1; i--) {
                r[i] = Character.digit(s[i], 10);
            }
            //r = [9, 8 ,1, 2, 1 ....
        }
    

    但似乎效率最高

答案 2 :(得分:1)

没见过。

“while(n!= 0){push(n%10); n = n / 10}”应该足够了。

如果你不想搞乱列表,那就去做两次。首先计算数组中的条目数,然后填充数组。

答案 3 :(得分:1)

我认为这可行,或者至少可以让你更进一步。

long x = 11234;
String[] s = Long.toString(x).split("");
int[] r = new int[s.length - 1];
for (int i = 1; i < s.length; i++)
  r[i - 1] = Integer.parseInt(s[i]);

答案 4 :(得分:1)

我提出了该方法的4个版本。

  1. 使用String.toCharArray和Character.getNumericValue()
  2. 使用带数组的模数
  3. 使用带Deque的模数
  4. 使用String.split()
  5. 使用非常大的值和Long.MAX_VALUE进行测试时,所有四个都会给出正确的结果。

    使用Long.MIN_VALUE测试时,结果是Math.abs(Long.MIN_VALUE)== Long.MIN_VALUE,所以你不能依赖它来摆脱减号!!所以我不得不摆脱它,所以我修改了版本。模数版本也使用Long.MIN_VALUE给出错误的值,数字是正确的,但它们都有负号。

    现在为了表现,我做了一些测试,我使用相同的输入运行每个方法10 000 000次,这是一个样本结果,但它非常具有代表性:

    输入:-5507235864653430347

    1:5110

    2:7235

    3:7564

    4:25487

    事实证明,到目前为止,获胜者是方法1. 2和3不可靠,4非常慢。

    public static int[] toIntArray(long x) {
        int neg = (x<0)?1:0;
        final char[] c = String.valueOf(x).toCharArray();
        final int s = c.length-neg;
        final int[] d = new int[s];
        for (int i = 0; i < s; i++) {
            d[i] = Character.getNumericValue(c[i+neg]);
        }
        if (neg==1) {
            d[0] = d[0] * -1;
        }
        return d;
    }
    
    public static int[] toIntArray2(long x) {
        int neg = (x<0)?1:0;
        final int s = String.valueOf(x).length()-neg;
        final int[] d = new int[s];
        for(int i =s-1 ; i > -1; i--) {
            d[i] = (int) (x%10);
            x = x/10;
        }
        return d;
    }
    
    public static Object[] toIntArray3(long x) {
        Deque<Integer> d = new ArrayDeque<Integer>(10);
        if(x==0){
            d.push(0);
            return d.toArray();
        }
        while(x != 0) {
            d.push((int) (x%10));
            x = x/10;
        }
        return  d.toArray();
    }
    
    public static int[] toIntArray4(long x) {
        int neg = (x<0)?1:0;
        final String[] c = String.valueOf(x).split("");
        final int s = c.length-neg;
        final int[] d = new int[s-1];
        for (int i = 1; i < s; i++) {
            d[i-1] = Integer.parseInt(c[i+neg]);
        }
        if (neg==1) {
            d[0] = d[0] * -1;
        }
        return d;
    }
    

答案 5 :(得分:0)

首先,我不知道任何现有的库方法可以做你想要的,我想不出一个好方法来搜索它。 (如果有人能解决这个问题,他们应该获得诺贝尔奖!)

涉及创建/拆分字符串或使用BigInteger的所有答案都是不必要的低效率。这是我的解决方案:

public int[] toDigitsArray(long num) {
    if (num < 0) {
        throw new IllegalArgumentException("negative num");
    } else if (num == 0) {
        return new int[]{0};  // simplifies the rest of the code
    }
    int[] tmp = new int[20];  // big enough to hold all digits of Long.MAX_VALUE
    int i = tmp.length - 1;
    while (num != 0) {
        tmp[i--] = num % 10;
        num = num / 10;
    }
    int[] res = new int[tmp.length - i];
    System.arraycopy(tmp, i + 1, res.length, res, 0);
    return res;
}

(我没有编译/测试过这个...但是专注于算法。)