📜  分离数组中的质数和非质数

📅  最后修改于: 2021-09-03 13:49:45             🧑  作者: Mango

给定一个大小为N的数组arr[] ,任务是重新排列数组元素,使所有素数都放在非素数之前。

例子:

朴素的方法:解决这个问题的最简单的方法是制作两个数组,分别存储素数非素数数组元素,并打印素数和非素数。

时间复杂度: O(N*sqrt(N))
辅助空间: O(N)

Alternate Approach:为了优化上述方式的辅助空间,解决这个问题的思路是使用Two-Pointer Approach。请按照以下步骤解决问题:

  • 左边的两个指针初始化为0右边的数组末尾为(N – 1)
  • 遍历数组直到小于并执行以下操作:
    • 继续递增指针,直到指向左索引的元素为质数。
    • 继续递减指针,直到指向左索引的元素是非质数。
    • 如果left小于right交换 arr[left]arr[right]并增加left并减少right 1
  • 完成上述步骤后,打印更新数组arr[]

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to swap two numbers a and b
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
 
// Function to check if a number n
// is a prime number of not
bool isPrime(int n)
{
    // Edges Cases
    if (n <= 1)
        return false;
 
    if (n <= 3)
        return true;
 
    // To skip middle five numbers
    if (n % 2 == 0 || n % 3 == 0)
        return false;
 
    // Checks for prime or non prime
    for (int i = 5;
         i * i <= n; i = i + 6) {
 
        // If n is divisible by i
        // or i + 2, return false
        if (n % i == 0
            || n % (i + 2) == 0)
            return false;
    }
 
    // Otherwise, the
    // number is prime
    return true;
}
 
// Function to segregate the primes
// and non-primes present in an array
void segregatePrimeNonPrime(
    int arr[], int N)
{
    // Initialize left and right pointers
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right) {
 
        // Increment left while array
        // element at left is prime
        while (isPrime(arr[left]))
            left++;
 
        // Decrement right while array
        // element at right is non-prime
        while (!isPrime(arr[right]))
            right--;
 
        // If left < right, then swap
        // arr[left] and arr[right]
        if (left < right) {
 
            // Swapp arr[left] and arr[right]
            swap(&arr[left], &arr[right]);
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for (int i = 0; i < N; i++)
        cout << arr[i] << " ";
}
 
// Driver Code
int main()
{
    int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    segregatePrimeNonPrime(arr, N);
 
    return 0;
}


Java
// java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
 
public class GFG {
 
    // Function to check if a number n
    // is a prime number of not
    static boolean isPrime(int n)
    {
        // Edges Cases
        if (n <= 1)
            return false;
 
        if (n <= 3)
            return true;
 
        // To skip middle five numbers
        if (n % 2 == 0 || n % 3 == 0)
            return false;
 
        // Checks for prime or non prime
        for (int i = 5; i * i <= n; i = i + 6) {
 
            // If n is divisible by i
            // or i + 2, return false
            if (n % i == 0 || n % (i + 2) == 0)
                return false;
        }
 
        // Otherwise, the
        // number is prime
        return true;
    }
 
    // Function to segregate the primes
    // and non-primes present in an array
    static void segregatePrimeNonPrime(int arr[], int N)
    {
        // Initialize left and right pointers
        int left = 0, right = N - 1;
 
        // Traverse the array
        while (left < right) {
 
            // Increment left while array
            // element at left is prime
            while (isPrime(arr[left]))
                left++;
 
            // Decrement right while array
            // element at right is non-prime
            while (!isPrime(arr[right]))
                right--;
 
            // If left < right, then swap
            // arr[left] and arr[right]
            if (left < right) {
 
                // Swapp arr[left] and arr[right]
                int temp = arr[right];
                arr[right] = arr[left];
                arr[left] = temp;
 
                left++;
                right--;
            }
        }
 
        // Print segregated array
        for (int i = 0; i < N; i++)
            System.out.print(arr[i] + " ");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
 
        int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
        int N = arr.length;
 
        segregatePrimeNonPrime(arr, N);
    }
}
 
// This code is contributed by Kingash.


Python3
# Python3 program for the above approach
 
# Function to check if a number n
# is a prime number of not
def isPrime(n):
     
    # Edges Cases
    if (n <= 1):
        return False
 
    if (n <= 3):
        return True
 
    # To skip middle five numbers
    if (n % 2 == 0 or n % 3 == 0):
        return False
 
    # Checks for prime or non prime
    i = 5
     
    while (i * i <= n):
 
        # If n is divisible by i or i + 2,
        # return False
        if (n % i == 0 or n % (i + 2) == 0):
            return False
 
        i += 6
         
    # Otherwise, the number is prime
    return True
 
# Function to segregate the primes and
# non-primes present in an array
def segregatePrimeNonPrime(arr, N):
     
    # Initialize left and right pointers
    left, right = 0, N - 1
 
    # Traverse the array
    while (left < right):
 
        # Increment left while array element
        # at left is prime
        while (isPrime(arr[left])):
            left += 1
 
        # Decrement right while array element
        # at right is non-prime
        while (not isPrime(arr[right])):
            right -= 1
 
        # If left < right, then swap
        # arr[left] and arr[right]
        if (left < right):
 
            # Swapp arr[left] and arr[right]
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
 
    # Print segregated array
    for num in arr:
        print(num, end = " ")
 
# Driver code
arr = [ 2, 3, 4, 6, 7, 8, 9, 10 ]
N = len(arr)
 
segregatePrimeNonPrime(arr, N)
 
# This code is contributed by girishthatte


C#
// C# program for the above approach
using System;
 
class GFG{
 
// Function to check if a number n
// is a prime number of not
static bool isPrime(int n)
{
     
    // Edges Cases
    if (n <= 1)
        return false;
 
    if (n <= 3)
        return true;
 
    // To skip middle five numbers
    if (n % 2 == 0 || n % 3 == 0)
        return false;
 
    // Checks for prime or non prime
    for(int i = 5; i * i <= n; i = i + 6)
    {
         
        // If n is divisible by i
        // or i + 2, return false
        if (n % i == 0 || n % (i + 2) == 0)
            return false;
    }
 
    // Otherwise, the
    // number is prime
    return true;
}
 
// Function to segregate the primes
// and non-primes present in an array
static void segregatePrimeNonPrime(int[] arr, int N)
{
     
    // Initialize left and right pointers
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right)
    {
         
        // Increment left while array
        // element at left is prime
        while (isPrime(arr[left]))
            left++;
 
        // Decrement right while array
        // element at right is non-prime
        while (!isPrime(arr[right]))
            right--;
 
        // If left < right, then swap
        // arr[left] and arr[right]
        if (left < right)
        {
             
            // Swapp arr[left] and arr[right]
            int temp = arr[right];
            arr[right] = arr[left];
            arr[left] = temp;
 
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for(int i = 0; i < N; i++)
        Console.Write(arr[i] + " ");
}
 
// Driver Code
public static void Main(string[] args)
{
    int[] arr = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = arr.Length;
 
    segregatePrimeNonPrime(arr, N);
}
}
 
// This code is contributed by ukasp


Javascript


C++
// C++ program for the above approach
#include 
#include 
using namespace std;
bool prime[10000001];
 
// Function to swap two numbers a and b
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
 
// Function to generate prime numbers
// using Sieve of Eratosthenes
void SieveOfEratosthenes(int n)
{
    memset(prime, true, sizeof(prime));
 
    for (int p = 2; p * p <= n; p++) {
 
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true) {
 
            // Update all multiples of p
            for (int i = p * p;
                 i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes
// and non-primes
void segregatePrimeNonPrime(
    int arr[], int N)
{
    // Generate all primes till 10^7
    SieveOfEratosthenes(10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right) {
 
        // Increment left while array
        // element at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array
        // element at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap
        // arr[left] and arr[right]
        if (left < right) {
 
            // Swap arr[left] and arr[right]
            swap(&arr[left], &arr[right]);
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for (int i = 0; i < N; i++)
        cout << arr[i] << " ";
}
 
// Driver code
int main()
{
    int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    segregatePrimeNonPrime(arr, N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to generate prime numbers
// using Sieve of Eratosthenes
public static void SieveOfEratosthenes(boolean[] prime,
                                       int n)
{
    for(int p = 2; p * p <= n; p++)
    {
         
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true)
        {
             
            // Update all multiples of p
            for(int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes and non-primes
public static void segregatePrimeNonPrime(boolean[] prime,
                                          int arr[], int N)
{
     
    // Generate all primes till 10^
    SieveOfEratosthenes(prime, 10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right)
    {
         
        // Increment left while array element
        // at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array element
        // at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap arr[left]
        // and arr[right]
        if (left < right)
        {
             
            // Swap arr[left] and arr[right]
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for(int i = 0; i < N; i++)
        System.out.printf(arr[i] + " ");
}
 
// Driver code
public static void main(String[] args)
{
    boolean[] prime = new boolean[10000001];
    Arrays.fill(prime, true);
    int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = arr.length;
 
    // Function Call
    segregatePrimeNonPrime(prime, arr, N);
}
}
 
// This code is contributed by girishthatte


Python3
# Python3 program for the above approach
 
# Function to generate prime numbers
# using Sieve of Eratosthenes
def SieveOfEratosthenes(prime, n):
     
    p = 2
     
    while (p * p <= n):
         
        # If prime[p] is unchanged,
        # then it is a prime
        if (prime[p] == True):
             
            # Update all multiples of p
            i = p * p
             
            while (i <= n):
                prime[i] = False
                i += p
                 
        p += 1
 
# Function to segregate the primes and non-primes
def segregatePrimeNonPrime(prime, arr, N):
 
    # Generate all primes till 10^7
    SieveOfEratosthenes(prime, 10000000)
 
    # Initialize left and right
    left, right = 0, N - 1
 
    # Traverse the array
    while (left < right):
 
        # Increment left while array element
        # at left is prime
        while (prime[arr[left]]):
            left += 1
 
        # Decrement right while array element
        # at right is non-prime
        while (not prime[arr[right]]):
            right -= 1
 
        # If left < right, then swap arr[left]
        # and arr[right]
        if (left < right):
             
            # Swap arr[left] and arr[right]
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
 
    # Print segregated array
    for num in arr:
        print(num, end = " ")
 
# Driver code
arr = [ 2, 3, 4, 6, 7, 8, 9, 10 ]
N = len(arr)
prime = [True] * 10000001
 
# Function Call
segregatePrimeNonPrime(prime, arr, N)
 
# This code is contributed by girishthatte


C#
// C# program for the above approach
using System;
 
class GFG{
     
// Function to generate prime numbers
// using Sieve of Eratosthenes
public static void SieveOfEratosthenes(bool[] prime,
                                       int n)
{
    for(int p = 2; p * p <= n; p++)
    {
         
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true)
        {
             
            // Update all multiples of p
            for(int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes and non-primes
public static void segregatePrimeNonPrime(bool[] prime,
                                          int []arr, int N)
{
     
    // Generate all primes till 10^
    SieveOfEratosthenes(prime, 10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right)
    {
         
        // Increment left while array element
        // at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array element
        // at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap arr[left]
        // and arr[right]
        if (left < right)
        {
             
            // Swap arr[left] and arr[right]
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for(int i = 0; i < N; i++)
        Console.Write(arr[i] + " ");
}
 
// Driver code
public static void Main(String[] args)
{
    bool[] prime = new bool[10000001];
    for(int i = 0; i < prime.Length; i++)
        prime[i] = true;
         
    int []arr = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = arr.Length;
 
    // Function Call
    segregatePrimeNonPrime(prime, arr, N);
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:
2 3 7 6 4 8 9 10

时间复杂度: O(N*sqrt(N))
辅助空间: O(1)

高效方法:可以通过使用埃拉托色尼筛法(Sieve of Eratosthenes)来优化上述方法,以在恒定时间内查找数字是素数还是非素数。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
#include 
using namespace std;
bool prime[10000001];
 
// Function to swap two numbers a and b
void swap(int* a, int* b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
 
// Function to generate prime numbers
// using Sieve of Eratosthenes
void SieveOfEratosthenes(int n)
{
    memset(prime, true, sizeof(prime));
 
    for (int p = 2; p * p <= n; p++) {
 
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true) {
 
            // Update all multiples of p
            for (int i = p * p;
                 i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes
// and non-primes
void segregatePrimeNonPrime(
    int arr[], int N)
{
    // Generate all primes till 10^7
    SieveOfEratosthenes(10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right) {
 
        // Increment left while array
        // element at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array
        // element at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap
        // arr[left] and arr[right]
        if (left < right) {
 
            // Swap arr[left] and arr[right]
            swap(&arr[left], &arr[right]);
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for (int i = 0; i < N; i++)
        cout << arr[i] << " ";
}
 
// Driver code
int main()
{
    int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    segregatePrimeNonPrime(arr, N);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
 
class GFG{
     
// Function to generate prime numbers
// using Sieve of Eratosthenes
public static void SieveOfEratosthenes(boolean[] prime,
                                       int n)
{
    for(int p = 2; p * p <= n; p++)
    {
         
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true)
        {
             
            // Update all multiples of p
            for(int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes and non-primes
public static void segregatePrimeNonPrime(boolean[] prime,
                                          int arr[], int N)
{
     
    // Generate all primes till 10^
    SieveOfEratosthenes(prime, 10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right)
    {
         
        // Increment left while array element
        // at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array element
        // at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap arr[left]
        // and arr[right]
        if (left < right)
        {
             
            // Swap arr[left] and arr[right]
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for(int i = 0; i < N; i++)
        System.out.printf(arr[i] + " ");
}
 
// Driver code
public static void main(String[] args)
{
    boolean[] prime = new boolean[10000001];
    Arrays.fill(prime, true);
    int arr[] = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = arr.length;
 
    // Function Call
    segregatePrimeNonPrime(prime, arr, N);
}
}
 
// This code is contributed by girishthatte

蟒蛇3

# Python3 program for the above approach
 
# Function to generate prime numbers
# using Sieve of Eratosthenes
def SieveOfEratosthenes(prime, n):
     
    p = 2
     
    while (p * p <= n):
         
        # If prime[p] is unchanged,
        # then it is a prime
        if (prime[p] == True):
             
            # Update all multiples of p
            i = p * p
             
            while (i <= n):
                prime[i] = False
                i += p
                 
        p += 1
 
# Function to segregate the primes and non-primes
def segregatePrimeNonPrime(prime, arr, N):
 
    # Generate all primes till 10^7
    SieveOfEratosthenes(prime, 10000000)
 
    # Initialize left and right
    left, right = 0, N - 1
 
    # Traverse the array
    while (left < right):
 
        # Increment left while array element
        # at left is prime
        while (prime[arr[left]]):
            left += 1
 
        # Decrement right while array element
        # at right is non-prime
        while (not prime[arr[right]]):
            right -= 1
 
        # If left < right, then swap arr[left]
        # and arr[right]
        if (left < right):
             
            # Swap arr[left] and arr[right]
            arr[left], arr[right] = arr[right], arr[left]
            left += 1
            right -= 1
 
    # Print segregated array
    for num in arr:
        print(num, end = " ")
 
# Driver code
arr = [ 2, 3, 4, 6, 7, 8, 9, 10 ]
N = len(arr)
prime = [True] * 10000001
 
# Function Call
segregatePrimeNonPrime(prime, arr, N)
 
# This code is contributed by girishthatte

C#

// C# program for the above approach
using System;
 
class GFG{
     
// Function to generate prime numbers
// using Sieve of Eratosthenes
public static void SieveOfEratosthenes(bool[] prime,
                                       int n)
{
    for(int p = 2; p * p <= n; p++)
    {
         
        // If prime[p] is unchanged,
        // then it is a prime
        if (prime[p] == true)
        {
             
            // Update all multiples of p
            for(int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
}
 
// Function to segregate the primes and non-primes
public static void segregatePrimeNonPrime(bool[] prime,
                                          int []arr, int N)
{
     
    // Generate all primes till 10^
    SieveOfEratosthenes(prime, 10000000);
 
    // Initialize left and right
    int left = 0, right = N - 1;
 
    // Traverse the array
    while (left < right)
    {
         
        // Increment left while array element
        // at left is prime
        while (prime[arr[left]])
            left++;
 
        // Decrement right while array element
        // at right is non-prime
        while (!prime[arr[right]])
            right--;
 
        // If left < right, then swap arr[left]
        // and arr[right]
        if (left < right)
        {
             
            // Swap arr[left] and arr[right]
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
 
    // Print segregated array
    for(int i = 0; i < N; i++)
        Console.Write(arr[i] + " ");
}
 
// Driver code
public static void Main(String[] args)
{
    bool[] prime = new bool[10000001];
    for(int i = 0; i < prime.Length; i++)
        prime[i] = true;
         
    int []arr = { 2, 3, 4, 6, 7, 8, 9, 10 };
    int N = arr.Length;
 
    // Function Call
    segregatePrimeNonPrime(prime, arr, N);
}
}
 
// This code is contributed by Princi Singh

Javascript


输出:
2 3 7 6 4 8 9 10

时间复杂度: O(N*log(log(N)))
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live