简体   繁体   English

2个数之和为素数

[英]Sum of 2 numbers being prime

I am working on a program where given a number say 4, I need to find out the possible ways to use all the numbers from 1 to 4, in such a way that the numbers next to each other sum to a prime number.我正在开发一个程序,其中给定一个数字,比如 4,我需要找出使用从 1 到 4 的所有数字的可能方法,这样彼此相邻的数字总和为素数。

For example, if given number is 4, then possible ways are:例如,如果给定的数字是 4,那么可能的方法是:

1 2 3 4
1 4 3 2

I am using the below approach, please let me know if there is any simplified approach:我正在使用以下方法,如果有任何简化的方法,请告诉我:

Step 1: Find all prossible combinations of numbers 1 to 4, say第 1 步:找出数字 1 到 4 的所有可能组合,例如

1 2 3 4
1 3 2 4
1 3 4 2
2 3 4 1
2 3 1 4
etc

Step 2: Find out what series matches the given requirement, and increment a counter.第 2 步:找出符合给定要求的系列,并增加一个计数器。 Finally display the value of counter.最后显示计数器的值。

Is there a better approach to this?有没有更好的方法来解决这个问题?

Here is a solution that uses backtracking to speed up the program.这是一个使用回溯来加速程序的解决方案。

public class PrimeSum {

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

  private static void findSolutions(int[] a, int n) {
    if(n >= a.length) {
      System.out.println(java.util.Arrays.toString(a));
    } else {
      for(int i = n; i < a.length; i++) {
        if(n == 0 || isPrime(a[n - 1] + a[i])) {
          int t = a[n];
          a[n] = a[i];
          a[i] = t;
          findSolutions(a, n + 1);
          t = a[n];
          a[n] = a[i];
          a[i] = t;
        }
      }
    }
  }

  public static void main(String[] args) {
    int[] a = new int[4];
    for(int i = 0; i < a.length; i++) {
      a[i] = i + 1;
    }
    findSolutions(a, 0);
  }
}

I took a somewhat different approach.我采取了一些不同的方法。 First I look at which pairs are allowed.首先我看看哪些对是允许的。 So, when you start with the number 4, you have the following options:因此,当您从数字 4 开始时,您有以下选择:

  • combine 1 with 2 or 4将 1 与 2 或 4 结合
  • combine 2 with 1 or 3将 2 与 1 或 3 结合
  • combine 3 with 2 or 4将 3 与 2 或 4 结合
  • combine 4 with 1 or 3将 4 与 1 或 3 结合

What you need to do now is, to start with the potential sequences of two numbers:您现在需要做的是,从两个数字的潜在序列开始:

  • 1,2 1,2
  • 1,4 1,4
  • 2,1 2,1
  • 2,3 2,3
  • 3,2 3,2
  • 3,4 3,4
  • 4,1 4,1
  • 4,3 4,3

After that you just start to extent them.之后,您就可以开始扩展它们了。 So in the case of the first (1,2), you have the option to add a 1 or a 3, as for 2 the available options are 1 or 3 (see first bullet-list).因此,在第一个 (1,2) 的情况下,您可以选择添加 1 或 3,至于 2,可用选项是 1 或 3(请参阅第一个项目符号列表)。 That gives the sequences 1,2,1 and 1,2,3.这给出了序列 1,2,1 和 1,2,3。 As you can't use numbers twice, the first option can be ignored.由于您不能使用两次数字,因此可以忽略第一个选项。

That way, you end up with the following sequences of three numbers:这样,您最终会得到以下三个数字的序列:

  • 1,2,3 1,2,3
  • 1,4,3 1,4,3
  • 2,1,4 2,1,4
  • 2,3,4 2,3,4
  • 3,2,1 3,2,1
  • 3,2,4 3,2,4
  • 3,4,1 3,4,1
  • 4,1,2 4,1,2
  • 4,3,2 4,3,2

Continue doing this and you end up with the solution:继续这样做,你最终得到了解决方案:

  • 1,2,3,4 1、2、3、4
  • 1,4,3,2 1,4,3,2
  • 2,1,4,3 2,1,4,3
  • 2,3,4,1 2,3,4,1
  • 3,2,1,4 3,2,1,4
  • 3,4,1,2 3,4,1,2
  • 4,1,2,3 4,1,2,3
  • 4,3,2,1 4,3,2,1

Here is my solution in code:这是我的代码解决方案:

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;


public class Main2 {
    static Scanner sc = new Scanner(System.in);

    private static boolean isPrime(int number) {
        if(number % 2 == 0) {
            return false;
        }
        for(int i = 3; i * i <= number; i += 2) {
          if(number % i == 0) return false;
        }
        return true;
      }

    public static void main(String[] args) {

        //Get number from user
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter a value");
        int number = scanner.nextInt();

        LinkedList<LinkedList<Integer>> solutions = new LinkedList<>();

        //Make a HashMap with all the viable combinations using two numbers
        //Make a HashMap with all potential combinations
        HashMap<Integer, LinkedList<Integer>> viableCombinations = new HashMap<>();
        LinkedList<LinkedList<Integer>> potentialSolutions = new LinkedList<>();
        for (int i = 1; i <= number; i++) {
            for (int j = i + 1; j <= number; j++) {
                if (isPrime(i+j)) {
                    if (viableCombinations.containsKey(i)) {
                        viableCombinations.get(i).add(j);
                    }
                    else {
                        LinkedList<Integer> newCombination = new LinkedList<Integer>();
                        newCombination.add(j);
                        viableCombinations.put(i, newCombination);
                    }
                    if (viableCombinations.containsKey(j)) {
                        viableCombinations.get(j).add(i);
                    }
                    else {
                        LinkedList<Integer> newCombination = new LinkedList<Integer>();
                        newCombination.add(i);
                        viableCombinations.put(j, newCombination);
                    }

                    LinkedList<Integer> combination = new LinkedList<>();
                    combination.add(i);
                    combination.add(j);
                    potentialSolutions.add(combination);
                    combination = new LinkedList<>();
                    combination.add(j);
                    combination.add(i);
                    potentialSolutions.add(combination);
                }
            }
        }

        //Extend HashMap with all viable combinations
        while (potentialSolutions.size() > 0) {
            LinkedList<Integer> potentialSolution = potentialSolutions.pop();
            if (potentialSolution.size() == number) {
                solutions.add(potentialSolution);
            }
            else {
                LinkedList<Integer> combinations = viableCombinations.get(potentialSolution.getLast());
                for (int i = 0; i < combinations.size(); i++) {
                    LinkedList<Integer> newPotentialSolution = new LinkedList<>(potentialSolution);
                    if (!newPotentialSolution.contains(combinations.get(i))) {
                        newPotentialSolution.add(combinations.get(i));
                        potentialSolutions.add(newPotentialSolution);
                    }
                }
            }

        }
        System.out.println(solutions);
    }
}

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

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