简体   繁体   English

如何使用数组在java中使用其质数对数字进行编码?

[英]How to encode a number using its prime factors in java using arrays?

I have this question I am trying to solve我有这个问题我想解决问题图片

I wrote this code我写了这段代码

public static int[] encodeNumber(int n) {
    int count = 0, base = n, mul = 1;

    for (int i = 2; i < n; i++) {
        if(n % i == 0 && isPrime(i)) {
            mul *= i;
            count++;
            if(mul == n) {
                break;
            }
            n /= i;
        }
    }

    System.out.println("count is " + count);

    int[] x = new int[count];

    int j = 0;

    for (int i = 2; i < base; i++) {
        if(n % i == 0 && isPrime(i)) {
            mul *= i;
            x[j] = i;
            j++;
            if(mul == n)    break;
            n /= i;
        }
        break;
    }

    return x;
}

public static boolean isPrime(int n) {
    if(n < 2)   return false;
    for (int i = 2; i < n; i++) {
        if(n % i == 0)  return false;
    }
    return true;
}

I am trying to get the number of its prime factors in a count variable and create an array with the count and then populate the array with its prime factors in the second loop.我试图在计数变量中获取其质因子的数量,并使用该计数创建一个数组,然后在第二个循环中使用其质因子填充该数组。

count is 3
[2, 0, 0]

with an input of 6936. The desired output is an array containing all its prime factors {2, 2, 2, 3, 17, 17} .输入为 6936。所需的输出是一个包含其所有质因子{2, 2, 2, 3, 17, 17}的数组。

Your count is wrong, because you count multiple factors like 2 and 17 of 6936 only once.您的count是错误的,因为您只计算了6936 217等多个因素一次。

I would recommend doing it similar to the following way, recursively: (this code is untested)我建议以类似于以下方式递归地执行此操作:(此代码未经测试)

void encodeNumberRecursive(int remainder, int factor, int currentIndex, Vector<Integer> results) {
     if(remainder<2) {
         return;
     }
     if(remainder % factor == 0) {
         results.push(factor);
         remainder /= factor; 
         currentIndex += 1; 
         encodeNumberRecursive(remainder , factor, currentIndex, results);  
     } else {
         do {
            factor += 1;
         } while(factor<remainder && !isPrime(factor));
         if(factor<=remainder) {
             encodeNumberRecursive(remainder , factor, currentIndex, results); 
         }
     }
}

Finally, call it with最后,调用它

Vector<Integer> results = new Vector<Integer>();
encodeNumberRecursive(n, 2, 0, results);

You can also do it without recursion, I just feel it is easier.你也可以不用递归来做,我只是觉得它更容易。

Well here is a piece of code I would start with.好吧,这是我要开始的一段代码。 It is not finished yet and I did not test it, but that's the way you should go basically.它还没有完成,我没有测试它,但基本上你应该这样做。

// First find the number of prime factors

int factorsCount = 0;
    int originalN = n;
    while (n > 1) {
       int p = findLowestPrimeFactor(n);
       n /= p;
       factorsCount++;
    }

    // Now create the Array of the appropriate size 

    int[] factors = new int[factorsCount];

    // Finally do the iteration from the first step again, but now filling the array.
    n = originalN;
    int k = 0;
    while (n > 1) {
       int p = findLowestPrimeFactor(n);
       factors[k] = p;
       k++;
       n = n / p;
    }

    return factors;

Having found a factor (on increasing candidates), you can assume it is prime, if you divide out the factor till the candidate no longer is a factor.找到一个因素(增加候选人),你可以假设它是素数,如果你把这个因素除掉,直到候选人不再是一个因素。

Your problem is not repeatedly dividing by the factor.您的问题不是重复除以因子。

public static int[] encodeNumber(int n) {
    if (n <= 1) {
        return null;
    }

    List<Integer> factors = new ArrayList<>();
    for (int i = 2; n != 1; i += 1 + (i&1)) {
        while (n % i == 0) { // i is automatically prime, as lower primes done.
            factors.add(i);
            n /= i;
        }
    }
    return factors.stream().mapToInt(Integer::intValue).toArray();
}

Without data structures, taking twice the time:没有数据结构,花费两倍的时间:

public static int[] encodeNumber(int n) {
    if (n <= 1) {
        return null;
    }
    // Count factors, not storing them:
    int factorCount = 0;
    int originalN = n;
    for (int i = 2; n != 1; i += 1 + (i&1)) {
        while (n % i == 0) {
            ++factorCount;
            n /= i;
        }
    }

    // Fill factors:
    n = originalN;
    int[] factors = new int[factorCount];
    factorCount = 0;
    for (int i = 2; n != 1; i += 1 + (i&1)) {
        while (n % i == 0) {
            factors[factorCount++] = i;
            n /= i;
        }
    }
    return factors;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM