【问题标题】:Counting non Prime Numbers计算非质数
【发布时间】:2020-02-06 19:38:46
【问题描述】:

我想创建一个从 int 数组返回非素数数量的方法。

我用来标记数组中素数的方法是这样的(这部分不需要任何改动):

public static int markNonePrimeNumbers(int[] array) {
        createInitialArray(100);
        for (int j = 2; j < array.length; j++) {
            for (int i = j * 2; i < array.length; i += j) {
                array[i] = 0;
            }
        }

我想修改它,使它可以返回 array[i] = 0 的数量并计算它。

我通过添加 HashMap 做到了这一点:

public static int[] markNonePrimeNumbers(int[] array) {
    createInitialArray(100);
    for (int j = 2; j < array.length; j++) {
        for (int i = j * 2; i < array.length; i += j) {
            array[i] = 0;
        }
    }
    Map<Integer, Integer> map = new HashMap<>();
    for (int key : array) {
        if (map.containsKey(key)) {
            int occurrence = map.get(key);
            occurrence++;
            map.put(key, occurrence);
        } else {
            map.put(key, 0);
        }
    }
    for (Integer key : map.keySet()) {
        int occurrence = map.get(key);
        System.out.println(occurrence);
    }

总的来说,我很接近,但我不知道如何从 Map 中删除所有大于 1 的索引。它已经计算了第一个索引上 0 的数量。

【问题讨论】:

    标签: java arrays hashmap sieve-of-eratosthenes


    【解决方案1】:

    这是我的解决方法。

    1) 首先创建一个非常简单的方法来检查一个数是否为素数。见下文:

    public static boolean checkPrime(int number) {
        if (number <= 1) {
            return false;
        }
        System.out.println(number);
    
        for (int i=2; i <= Math.sqrt(number); i++) {
            if(number % i == 0) {
                System.out.println(i);
                return false;
            } 
        }
        return true;
    
    }
    

    2) 创建另一个循环遍历数组的方法并调用上述方法:

    public static int numOfPrimesInArray(int[] arr){
        int counter = 0;
        for (int num: arr){
            if (!checkPrime(num)) counter++;
        }
        return counter;
    }
    

    3) 然后简单地从你的 main 方法中调用它:

    public static void main(String[] args){
        int[] nums = {1,2,3,5,6,7,8,9,10};
        int nonprimes = numOfPrimesInArray(nums);
        System.out.println(nonprimes);
    }
    

    如果我在写这篇文章时没有犯任何错误,应该给你数组中非素数的数量。

    【讨论】:

      【解决方案2】:

      您计算质数的方法不正确,因此您的计数不正确。您计算非素数数量的方法几乎是正确的。

      我已经修改了一些代码,以便在这里正常工作

      public static void main(String[] args){
      
              int[] array = new int[]{1,2,3,4,57,10,7,11,13,17,16};
              for (int i = 0; i < array.length; i++) {
                  int temp = 0;
                  for(int j=2;j<=array[i]/2;j++)
                  {
                      temp=array[i]%j;
                      if(temp==0)
                      {
                          array[i] = 0;
                          break;
                      }
                  }
              }
              Map<Integer, Integer> map = new HashMap<>();
              for (int key : array) {
                  if (map.containsKey(key)) {
                      int occurrence = map.get(key);
                      occurrence++;
                      map.put(key, occurrence);
                  } else {
                      map.put(key, 1);
                  }
              }
              if(map.containsKey(0)){
                  System.out.println(map.get(0));
              } else {
                  System.out.println("could not find");
              }
          }
      

      【讨论】:

      • 谢谢,使用 hashMap 的解决方案效果很好。谢谢你:)
      【解决方案3】:

      做到这一点的最佳方法之一是保留一个运行中的素数列表,然后检查该列表。第一部分是驱动程序代码,因此无需解释。

              int[] array = new int[] { 1,19, 2, 3, 4, 57, 10, 7, 11,
                      13, 17, 16 };
              List<Integer> nonPrimes = new ArrayList<>();
              for (int c : array) {
                  if (!isPrime(c)) {
                      nonPrimes.add(c);
                  }
              }
              System.out.println(nonPrimes);
      
      

      这里是主要查找方法的开始。要点如下:

      1. 它使用LinkedHashSet 来存储素数。
        一种。它维持秩序。
        湾。允许快速查找特定值

      2. 它会找到直到提交值的所有素数并存储它们。这只是 如果提交的值大于记录的最后一个素数,则完成。

      3. 随后的候选素数从记录的最后一个素数 + 2 开始。由于 2 之后的所有素数都是奇数,因此这也保证是下一个奇数值。候选人加 2 以跳过偶数。

      4. 为了检测候选者是否为素数,除以先前记录的素数(但仅限于候选者的square root)。

          static Set<Integer> primes = new LinkedHashSet<>() {
              {   // seed the first two primes.
                  add(2);
                  add(3);
              }
          };
      
          // last recorded prime
          static int lastPrime = 3;
      
          public static boolean isPrime(int val) {
              for (int candidate = lastPrime+2; candidate <= val; candidate += 2) {
                 int max = (int)(Math.sqrt(candidate)) + 1;
                  for (int p : primes) {
                      // if candidate is divisible by any prime, then discontinue
                      // testing and move on to next candidate via outer loop
                      if (candidate % p == 0) {
                          break;
                      }
                      // if the limit has been reached, then a prime has been
                      // found, so add to list of primes and continue with
                      // next candidate.  Only check up tot he square root of the candidate.
                      if (p >= max) {
                          // add new found prime to list
                          primes.add(candidate);
                          lastPrime = candidate;
                          break;
                      }
                  }
              }
              // Now check the newly built (if required) hash set to see if the passed value
              // is in the list.
              return primes.contains(val);
          }
      
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-03
        • 2015-06-04
        • 1970-01-01
        • 2014-09-08
        • 2012-04-06
        相关资源
        最近更新 更多