Movatterモバイル変換


[0]ホーム

URL:


Data Structures & Algorithms Tutorial

DSA - Mathematical Algorithms



Mathematical algorithms are well-defined procedures that are used in solving mathematical problems related to data structures. We can see its application in competitive programming, data science and other complex mathematical concepts. These algorithms teach us how to solve a given problem by thinking logically and efficiently.

Important Mathematical Algorithms

Some of the important mathematical algorithms are −

  • Euclid's Algorithm

  • Sieve of Eratosthenes

  • Binary Exponentiation

  • Modular Arithmetic

Here is the detailed explanation −

Euclid's Algorithm

Euclid's algorithm, also referred to as the Euclidean algorithm, is a method that is used to compute GCD of two given integers. The term GCD is an abbreviation that stands forgreatest common divisor. The GCD is also termed as highest common factor(HCF). It is defined as the largest integer that divides a given set of numbers.

Suppose, a given set of integers are A and B. Here's how the Euclidean Algorithm works to find their GCD −

  • If A is equal to 0 and B is the non-zero integer, then GCD(A, B) is B.

  • The GCD of two integers A and B remains unchanged on subtracting the smaller integer from the larger one. Therefore, repeating this process several times will result in GCD.

  • Recursively compute A mod B and when it becomes 0, we will get our GCD which is B.

Example

In the following example, we are going to illustrate how Euclid's algorithm works.

#include <stdio.h>int findGrtCmFact(int a, int b) {   if (b == 0) {      return a;   } else {      return findGrtCmFact(b, a % b);   }}int main() {   int valOne = 52;   int valTwo = 28;   printf("The GCD of %d and %d is: %d\n", valOne, valTwo, findGrtCmFact(valOne, valTwo));   return 0;}
#include <iostream>using namespace std;int findGrtCmFact(int a, int b) {   if (b == 0) {      return a;   } else {      return findGrtCmFact(b, a % b);   }}int main() {   int valOne = 52;   int valTwo = 28;   cout << "The GCD of " << valOne << " and " << valTwo << " is: " << findGrtCmFact(valOne, valTwo) << endl;   return 0;}
public class GrtComFactr {   public static int findGrtCmFact(int a, int b) {      if (b == 0) {         return a;      } else {         return findGrtCmFact(b, a % b);      }   }   public static void main(String[] args) {      int valOne = 52;      int valTwo = 28;      System.out.println("The GCD of " + valOne + " and " + valTwo + " is: " + findGrtCmFact(valOne, valTwo));   }}
def findGrtCmFact(a, b):   if b == 0:      return a   else:      return findGrtCmFact(b, a % b)valOne = 52valTwo = 28print("The GCD of {} and {} is: {}".format(valOne, valTwo, findGrtCmFact(valOne, valTwo)))

Output

The GCD of 52 and 28 is: 4

Sieve of Eratosthenes Algorithm

TheSieve of Eratosthenes algorithm is a way used for identifying prime numbers within a given range. The naive approach to finding prime numbers is by iterating over each number and checking whether the current number is prime or not. However, it is not the optimal solution.

Here's how the Sieve of Eratosthenes works −

  • Start with a list of numbers from 2 up to N. Initially, consider all these numbers as potential primes.

  • Begin with the first prime number, which is 2. Mark all multiples of 2 as composite. Move on to the next unmarked number in the list, which is the 3. Now, mark all multiples of 3 as composite.

  • After completing this process for all numbers up to n, we will be left with only the prime numbers that remain unmarked.

Example

The following example illustrates the working of Sieve of Eratosthenes algorithm.

#include <stdio.h>#include <stdbool.h>#include <string.h>// method to find primesvoid sieveOfEratos(int n) {   // initially assuming all values are prime   bool prm[n+1];   memset(prm, true, sizeof(prm));   // Loop over all numbers from 2 to sqrt(n)   for(int currPrm = 2; currPrm*currPrm <= n; currPrm++) {      // If current prime is still true, then it is a prime      if(prm[currPrm] == true) {         // Update all multiples of current prime         for(int i = currPrm*currPrm; i <= n; i += currPrm)            // Marking factor as not prime            prm[i] = false;        }   }   // to print the list of prime numbers   printf("List of first 50 prime numbers: \n");   for(int i = 2; i <= n; i++) {      if(prm[i] == true)         printf("%d ", i);     }}int main() {   int lmt = 50;    sieveOfEratos(lmt);   return 0;}
#include <iostream>#include <vector>using namespace std;class SvEratos {public:   // method to find primes   static void sieveOfEratos(int n) {      // initially assuming all values are prime      vector<bool> prm(n+1, true);      // Loop over all numbers from 2 to sqrt(n)      for(int currPrm = 2; currPrm*currPrm <= n; currPrm++) {         // If current prime is still true, then it is a prime         if(prm[currPrm] == true) {            // Update all multiples of current prime            for(int i = currPrm*currPrm; i <= n; i += currPrm)               // Marking factor as not prime               prm[i] = false;              }      }      // to print the list of prime numbers      cout << "List of first 50 prime numbers: " << endl;      for(int i = 2; i <= n; i++) {         if(prm[i] == true)            cout << i << " ";        }      cout << endl;   }};int main() {   int lmt = 50;    SvEratos::sieveOfEratos(lmt);   return 0;}
public class SvEratos {   // method to find primes   public static void sieveOfEratos(int n) {      // initially assuming all values are prime      boolean prm[] = new boolean[n+1];      for(int i=0; i<=n; i++)         prm[i] = true;      // Loop over all numbers from 2 to sqrt(n)      for(int currPrm = 2; currPrm*currPrm <=n; currPrm++) {         // If current prime is still true, then it is a prime         if(prm[currPrm] == true) {            // Update all multiples of current prime            for(int i = currPrm*currPrm; i <= n; i += currPrm)               // Marking factor as not prime               prm[i] = false;           }      }      // to print the list of prime numbers      System.out.println("List of first 50 prime numbers: ");      for(int i = 2; i <= n; i++) {         if(prm[i] == true)            System.out.print(i + " ");        }   }   public static void main(String[] args) {      int lmt = 50;       sieveOfEratos(lmt);   }}
def sieveOfEratos(n):    # initially assuming all values are prime    prm = [True for _ in range(n+1)]    # Loop over all numbers from 2 to sqrt(n)    currPrm = 2    while currPrm * currPrm <= n:        # If current prime is still true, then it is a prime        if prm[currPrm] == True:            # Update all multiples of current prime            for i in range(currPrm * currPrm, n+1, currPrm):                # Marking factor as not prime                prm[i] = False        currPrm += 1        # to print the list of prime numbers    print("List of first 50 prime numbers: ")    for i in range(2, n):        if prm[i] == True:            print(i, end=" ")# test the functionlmt = 50sieveOfEratos(lmt)

Output

List of first 50 prime numbers: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47

Binary Exponentiation Algorithm

Thebinary exponentiation algorithm is a procedure used to calculate the power of a given number. The naive approach to solve this type of problem i.e. np is by multiplying the number with itself p-1 times. However, it is a time-consuming process and not an efficient process.

Instead of the above approach, we can use the binary exponentiation algorithm which works as follows −

  • When the power of any given number is 0, the result will be 1.

  • If the number itself is even, use the following equation: ((n2)p/2), where n is the number and p is the power of that given number.

  • If the given number is odd, use the equation: (n*(n(p-1)/2)2).

Example

In this example, we will show how Binary Exponentiation algorithm works.

#include <stdio.h>// function to calculate powerint bnryExp(int bs, int ex) {   int output = 1;   while (ex > 0) {      if (ex % 2 == 1) {         output *= bs;      }      // Square of base      bs *= bs;       // Divide power by 2      ex >>= 1;    }   // Return the result stored in output   return output;}int main() {   int bs = 3;   int ex = 6;   // Print the result   int result = bnryExp(bs, ex);   printf("The output of %d to the power %d is: %d\n", bs, ex, result);   return 0;}
#include <iostream>using namespace std;// method to calculate powerint bnryExp(int bs, int ex) {   // to store output   int output = 1;   while (ex > 0) {      if (ex % 2 == 1) {         output *= bs;      }      // Square of base      bs *= bs;       // Divide power by 2      ex /= 2;    }   // Return the result stored in output   return output;}int main() {   int bs = 3;   int ex = 6;   int result = bnryExp(bs, ex);   // Print the result   cout << "The output of " << bs << " to the power " << ex << " is: " << result << endl;   return 0;}
public class Exponentiation {    // method to calculate power    public static int bnryExp(int bs, int ex) {        // to store output        int output = 1;        while (ex > 0) {            if (ex % 2 == 1) {                output *= bs;            }            // Square of base            bs *= bs;            // Divide power by 2            ex /= 2;        }        // Return the result stored in output        return output;    }    public static void main(String[] args) {        int bs = 3;        int ex = 6;        // Print the result        System.out.println("The output of " + bs + " to the power " + ex + " is: " + bnryExp(bs, ex));    }}
# method to calculate powerdef bnryExp(bs, ex):   # to store output   output = 1   while ex > 0:      if ex % 2 == 1:         output *= bs      bs *= bs        ex //= 2     return outputbs = 3ex = 6result = bnryExp(bs, ex)print(f"The output of {bs} to the power {ex} is: {result}")

Output

The output of 3 to the power 6 is: 729

Modular Arithmetic

Modular arithmetic is a set of rules that is applicable in computing modulus expression. This concept becomes important when handling large numbers in competitive programming. The core idea of modular arithmetic is to find the remainder of a number upon division by another number.

Important properties of modulo are as follows −

  • (m mod n) mod n is equal to m mod n

  • (m*n) mod m is equal to 0

  • (P / Q) mod m ((P mod m) / (Q mod m)) mod m

  • (P + Q) mod m = ((P mod m) + (Q mod m)) mod m

  • (P Q) mod m = ((P mod m) (Q mod m) + m) mod m

  • (P * Q) mod m = ((P mod m) * (Q mod m)) mod m

Example

The following example demonstrates the working of modular arithmetic.

#include <stdio.h>// function to perform additionint modAddition(int valOne, int valTwo, int mod) {   // to handle negative values   if (valOne < 0) {      valOne = (valOne % mod + mod) % mod;   }   if (valTwo < 0) {      valTwo = (valTwo % mod + mod) % mod;   }   // addition   int sum = (valOne + valTwo) % mod;   // to ensure output is non-negative   return (sum + mod) % mod;}int main() {   int valOne = 22;   int valTwo = 26;   int mod = 5;   int output = modAddition(valOne, valTwo, mod);   printf("Modular addition of %d and %d modulo %d is: %d\n", valOne, valTwo, mod, output);   return 0;}
#include <iostream>using namespace std;int modAddition(int valOne, int valTwo, int mod) {   // to handle negative values   if (valOne < 0) {      valOne = (valOne % mod + mod) % mod;   }   if (valTwo < 0) {      valTwo = (valTwo % mod + mod) % mod;   }   // addition   int sum = (valOne + valTwo) % mod;   // to ensure the result is non-negative   return (sum + mod) % mod;}int main() {   int valOne = 22;   int valTwo = 26;   int mod = 5;   int output = modAddition(valOne, valTwo, mod);   cout << "Modular addition of " << valOne << " and " << valTwo << " modulo " << mod << " is: " << output << endl;  return 0;}
public class ModAdd {    public static int modAddition(int valOne, int valTwo, int mod) {        // to handle negative values        if (valOne < 0) {            valOne = (valOne % mod + mod) % mod;        }        if (valTwo < 0) {            valTwo = (valTwo % mod + mod) % mod;        }        // addition        int sum = (valOne + valTwo) % mod;        // to ensure output is non-negative        return (sum + mod) % mod;    }    public static void main(String[] args) {        int valOne = 22;        int valTwo = 26;        int mod = 5;        int output = modAddition(valOne, valTwo, mod);        System.out.println("Modular addition of " + valOne + " and " + valTwo + " modulo " + mod + " is: " + output);    }}
def mod_addition(val_one, val_two, mod):  # to handle negative values  if val_one < 0:    val_one = (val_one % mod + mod) % mod  if val_two < 0:    val_two = (val_two % mod + mod) % mod  # addition   sum = (val_one + val_two) % mod  # to ensure output is non-negative  return (sum + mod) % modval_one = 22val_two = 26mod = 5output = mod_addition(val_one, val_two, mod)print(f"Modular addition of {val_one} and {val_two} modulo {mod} is: {output}")

Output

Modular addition of 22 and 26 modulo 5 is: 3
Print Page
Advertisements

[8]ページ先頭

©2009-2025 Movatter.jp