Java 如何在数组中保存素因式分解的值?

Java 如何在数组中保存素因式分解的值?,java,arrays,loops,multidimensional-array,prime-factoring,Java,Arrays,Loops,Multidimensional Array,Prime Factoring,我现在的问题是,我需要对给定的数字进行素数分解。然后我需要将值(除数和幂)存储到2d数组中x[0][]=除法器和x[1][]幂。 所以f.ex。如果数字是8,那么除法器是2,功率是3,因为2^3=8 这是我的代码: 我的第一步是检查数字1的数组是否为空 public static long[][] primfactorization(long givenNumber) { if (givenNumber == 1) { long [][] empty = {{},{}}

我现在的问题是,我需要对给定的数字进行素数分解。然后我需要将值(除数和幂)存储到2d数组中
x[0][]=除法器和x[1][]幂。

所以f.ex。如果数字是8,那么除法器是2,功率是3,因为2^3=8

这是我的代码:

我的第一步是检查数字1的数组是否为空

public static long[][] primfactorization(long givenNumber) {

    if (givenNumber == 1) {
        long [][] empty = {{},{}};
        return empty;
    }
然后第二步是声明一些变量,并创建稍后必须返回的2d数组(我也使用sqrt而不是Math.sqrt,因为这里禁止使用java api的类/方法)。这里的问题是,我知道第一个括号的大小必须是2,因为它只有2行(除法器和电源),但我还不知道应该在第二个括号中输入什么,因为我不知道每个数字将有多少个除法器

int index = 0;
int count = 0;
int i=2;
long z = (long) sqrt(n);
long[][] a = new long[2][ (int) z];
    
然后我从“实”素因子分解开始,它工作得非常好。这里的主要问题是我无法将除法器和幂保存到数组中。就像我通过使用一个名为index的新变量(在我的方法开始时声明)尝试的那样,但是它可以将同一个除法器保存多次f.ex
x[0][1]=2和x[0][2]=2
我只需要它一次。此外,电源还没有按预期工作,因为它从1开始,每次循环完成时只会增加1,但它应该增加出现的相同分频器的数量(例如,分频器2出现3次,然后电源应该是3)。提前感谢

while(givenNumber%2==0) {
givenNumber=givenNumber/2;
count++; //power   8 = 2.2.2 => count = 3
}
i++;
for (i = 3; i <= z; i = i+2) {
// While i divides l, print i and divide l
while (givenNumber%i == 0) {
    int temp = i;
 //ToDo: save the divider in array[0][]
    count++; //ToDo: save the power in array[1][]
    givenNumber = givenNumber/i;
    i = temp;
    a[0][index] = temp;
    a[1][index] = count;
    index++;
  }
}
return a;
}
while(给定编号%2==0){
给定编号=给定编号/2;
count++;//幂8=2.2.2=>count=3
}
i++;
对于(i=3;i
使用此功能:

  • 当数组
    x
    已满时,其大小可以增加任意数量
  • 执行完成后,可以将
    x
    裁剪到正确的大小
  • 这里有一个适当的工作程序,可以显示所有正在运行的程序。试着运行它

    import java.util.Arrays; // I am aware that imports are not allowed, but have used this class only for display of output
    import java.util.Scanner;
    class Factorizer {
        public static long[][] primfactorization(long n) {
            int index = 0;
            int count = 0;
            long z = (long) Math.sqrt(n);
            long[][] x = new long[2][5];
            for (int i = 2; i <= z; i = i+2) {
                count = 0;
                while (n%i == 0) {
                    count++;
                    n = n/i;
                }
                if (count > 0) {
                    x[0][index] = i;
                    x[1][index] = count;
                    index++;
                }
                if (index >= x[0].length) // resizing array when it is too small
                    x = resize(x, index + 5); // 5 being an arbitrary number
                if (i == 2)
                    --i;
            }
            return resize(x, index); //trimming down the size before returning
        }
        static long[][] resize(long[][] arr, int newSize) {
            long[][] temp = new long[2][newSize];
            for(int i = 0; i < arr[0].length && i < newSize; ++i) {
                temp[0][i] = arr[0][i];
                temp[1][i] = arr[1][i];
            }
            return temp;
        }
        public static void main (String[] args)
        {
            System.out.print("Enter a number: ");
            long n = new Scanner(System.in).nextLong();
            System.out.println (Arrays.deepToString(primfactorization(n)));
        }
    }
    
    import java.util.Arrays;//我知道不允许导入,但仅将此类用于显示输出
    导入java.util.Scanner;
    类因子分解器{
    公共静态长[][]primfactorization(长n){
    int指数=0;
    整数计数=0;
    long z=(long)Math.sqrt(n);
    long[]x=新长[2][5];
    对于(int i=2;i 0){
    x[0][index]=i;
    x[1][index]=计数;
    索引++;
    }
    if(index>=x[0].length)//当数组太小时调整其大小
    x=调整大小(x,索引+5);//5是任意数
    如果(i==2)
    --一,;
    }
    return resize(x,index);//在返回之前修剪大小
    }
    静态长[][]调整大小(长[][]arr,int newSize){
    long[]temp=new long[2][newSize];
    对于(int i=0;i
    最后说明:

  • 在案例1是参数的情况下,所做的特殊检查是不必要的。我已经删除了它
  • 有一种特殊情况,该程序不能完全正确地工作。如果素数作为参数给出,则它不作为因子包含。这是因为循环的
    只运行到
    sqrt(n)
    。可以通过将for循环的上限设置为
    n
    ,或者通过循环体中的另一个
    条件(如果
    )来纠正此问题

  • 我建议为此使用
    映射
    。键可以是实际因子和值,也可以是计数。这消除了包含数组超过其长度或必须过度分配空间以容纳潜在因子的可能性

    
    int[] test = { 25, 282, 301, 292922, Integer.MAX_VALUE };
    for (int n : test) {
        Map<Integer, Integer> factors = findFactors(n);
        System.out.println(n + " -> " + factors);
    }
    
    如果需要,可以在从方法返回因子之前或打印因子之前将映射转换为数组

    
    for (int n : test) {
        Map<Integer, Integer> factors = findFactors(n);
        int[][] results = factors.entrySet().stream()
                .map(e -> new int[] { e.getKey(), e.getValue() })
                .toArray(int[][]::new);
        System.out.println(n + " -> " + Arrays.deepToString(results));  
    }
    
    下面是返回映射的方法。请注意,
    biginger
    用于检查当前更新的值是否为素数。这对于实现最佳性能至关重要。例如,当一个非常大的数字是相对较小的素数和一个非常大的素数的乘积时。要查看差异,请尝试
    Integer.MAX_值
    有无该检查

    public static Map<Integer, Integer> findFactors(int val) {
        Map<Integer, Integer> factors = new HashMap<>();
    
        // the initial prime
        int prime = 2;
        int c = 1;
        
        while (val > 1) {
    
            // update divisions and add to the map.
            int count = 0;
            while (val % prime == 0) {
                count++;
                val /= prime;
            }
            if (count > 0) {
                factors.put(prime, count);
            }
            
            // now do a check to see if the current value is a prime.
            if (BigInteger.valueOf(val).isProbablePrime(99)) {
                factors.put(val, 1);
                break;
            }
            // compute next factor.
            prime = (c++ * 2 + 1);
            
        }
        return factors;
    }
    
    公共静态映射findFactors(int val){
    映射因子=新的HashMap();
    //初始质数
    int素数=2;
    int c=1;
    while(val>1){
    //更新分区并添加到地图中。
    整数计数=0;
    while(val%prime==0){
    计数++;
    val/=素数;
    }
    如果(计数>0){
    因子。put(prime,count);
    }
    //现在检查当前值是否为素数。
    if(BigInteger.valueOf(val.isProbablePrime(99)){
    因子put(val,1);
    打破
    }
    //计算下一个因子。
    素数=(c++*2+1);
    }
    回报因素;
    }
    

    注:
    Integer.MAX_VALUE
    是一个2n-1形式的a,其中
    n
    是一个素数。在这种情况下,
    n=31

    不要在内环内增加
    索引;在内环之后,在外环的末端,即您要移动到下一个除数的地方进行。您必须为此使用数组吗地图会更好。你可以随时将地图转换为数组以获得最终结果。非常感谢你的帮助。只是我需要使用数组,不能使用列表,但其他的确实帮助了我很多lot@EgZoShift我想澄清的是
    
    25 -> {5=2}
    282 -> {2=1, 3=1, 47=1}
    301 -> {7=1, 43=1}
    292922 -> {2=1, 7=4, 61=1}
    2147483647 -> {2147483647=1}
    
    
    for (int n : test) {
        Map<Integer, Integer> factors = findFactors(n);
        int[][] results = factors.entrySet().stream()
                .map(e -> new int[] { e.getKey(), e.getValue() })
                .toArray(int[][]::new);
        System.out.println(n + " -> " + Arrays.deepToString(results));  
    }
    
    25 -> [[5, 2]]
    282 -> [[2, 1], [3, 1], [47, 1]]
    301 -> [[7, 1], [43, 1]]
    292922 -> [[2, 1], [7, 4], [61, 1]]
    2147483647 -> [[2147483647, 1]]
    
    public static Map<Integer, Integer> findFactors(int val) {
        Map<Integer, Integer> factors = new HashMap<>();
    
        // the initial prime
        int prime = 2;
        int c = 1;
        
        while (val > 1) {
    
            // update divisions and add to the map.
            int count = 0;
            while (val % prime == 0) {
                count++;
                val /= prime;
            }
            if (count > 0) {
                factors.put(prime, count);
            }
            
            // now do a check to see if the current value is a prime.
            if (BigInteger.valueOf(val).isProbablePrime(99)) {
                factors.put(val, 1);
                break;
            }
            // compute next factor.
            prime = (c++ * 2 + 1);
            
        }
        return factors;
    }