Как найти нод в си шарп

Сегодня разберём древний и красивый Алгоритм Евклида для нахождения наибольшего общего делителя (НОД) двух чисел, и запрограммируем его на языке C#.

Евклид – древнегреческий учёный, философ, математик, живший в 3 веке до н. э.

Где применяется алгоритм Евклида ?

  • Криптографический алгоритм с открытым ключом RSA.
  • Является основным инструментом для доказательства теорем в современной теории чисел.

Алгоритм ЕвклидаЭффективный алгоритм для нахождения наибольшего общего делителя (НОД) двух целых чисел.

Наибольший общий делитель

Например, для чисел 12 и 8 наибольший общий делитель (НОД) равен 4.

Алгоритм Евклида (метод вычитания)

Основное правило Алгоритма Евклида для метода вычитания:

Алгоритм Евклида

Т.е. можно заменить большее число – разностью двух чисел, и НОД останется тем же.

Составим алгоритм:

Блок-схема алгоритма Евклида (метод вычитания)

Сначала вводятся числа m, n. Затем входим в цикл. Цикл выполняется пока m и n не равны. Если эти переменные равны, то можно выйти из цикла и распечатать любое число (m или n). Действительно, ведь наибольший общий делитель (НОД) двух одинаковых чисел равен этому числу. В самом цикле заменяем наибольшее число разностью этих чисел, исходя из закономерности описанной выше.
Рано или поздно числа станут равными, и это значение и будет НОД.

Запрограммируем Алгоритм Евклида на языке C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp38
{
    class Program
    {
        static void Main(string[] args)
        {
            int m, n, nod;
            m = Convert.ToInt32(Console.ReadLine());
            n = Convert.ToInt32(Console.ReadLine());

            while(m != n)
            {
                if(m > n)
                {
                    m = m - n;
                }
                else
                {
                    n = n - m;
                }
            }

            nod = n;
            Console.WriteLine("НОД: " + nod);

            Console.ReadKey();
        }
    }
}

Алгоритм Евклида (метод деления)

Можно алгоритм Евклида написать и через остаток от деления!

Блок-схема алгоритма Евклида (метод деления)

Где символ % – это остаток от деления.

Запрограммируем метод деления Алгоритма Евклида на C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp38
{
    class Program
    {
        static void Main(string[] args)
        {
            int m, n, nod;
            m = Convert.ToInt32(Console.ReadLine());
            n = Convert.ToInt32(Console.ReadLine());

            while(m!= 0 && n!=0)
            {
                if(m > n)
                {
                    m = m % n;
                }
                else
                {
                    n = n % m;
                }
            }

            nod = m + n;
            Console.WriteLine("НОД: " + nod);

            Console.ReadKey();
        }
    }
}

На этом всё, удачи!

Сортировка слиянием (merge sort) на C#

Привет! Сегодня рассмотрим крутой метод сортировки слиянием….

Категория: Алгоритмы  Подкатегория: Сортировка

Дата: 23-10-2022 в 13:42:22
0

Алгоритм Евклида может быть использован для эффективного вычисления наибольшего общего делителя (НОД) для двух целых значений. Эта статья описывает алгоритм и предоставляет несколько методов C #, которые вычисляют НОД.

Наибольший общий делитель

Алгоритм Евклида представляет собой алгоритм, описанный греческим математиком Евклидом Александрийским. Алгоритм пытается вычислить наибольший общий делитель (НОД) двух сколь угодно больших целых чисел; НОД является наибольшим целым числом, которое может разделять два значения без остатка. Алгоритм использует тот факт, что, когда два числа делят общий делитель, вычитание меньшего числа из большего дает результат, который также разделяет общий делитель.

В качестве примера рассмотрим значения 320 и 120. НОД этих двух чисел – 40. Если процесс вычитания меньшего числа из большего числа повторяется, со временем одно из значений станет нулевым. В этот момент другое значение будет содержать НОД для исходной пары. Этот итерационный процесс для наших значений примера дает следующие результаты:

320 - 120 = 200
200 - 120 = 80
120 - 80 = 40
80 - 40 = 40
40 - 40 = 0

Окончательный расчет дает нулевой результат, который оставил бы два значения 40 и ноль. Следовательно, НОД – это значение 40.

Реализация алгоритма Евклида

Для первой реализации алгоритма мы будем непосредственно следовать шагам, описанным выше. Мы создадим статический метод, который имеет два целочисленных параметра и возвращает третье целое число, являющееся НОД. Метод статичен, поэтому его можно легко вызвать из метода Main приложения консоли без создания экземпляров объектов. Вы можете решить реализовать его как метод экземпляра для своего собственного проекта.

Метод состоит из нескольких этапов. Сначала создается цикл while, который будет продолжать обработку до тех пор, пока одно из значений не будет сведено к нулю. Внутри цикла меньшее из двух значений вычитается из большего. Как только цикл завершился, одно значение будет равно нулю, а другое будет содержать НОД. Возврат НОД осуществляется путем нахождения большего из двух значений.

Примечание: Код в этой статье предполагает, что оба целых числа положительны.

Чтобы создать метод, добавьте следующий код:

        static int GetNOD (int val1, int val2)
{
    while ((val1 !=0) && (val2 != 0))
    {
        if (val1> val2)
            val1 -= val2;
        else
            val2 -= val1;
    }

    return Math.Max(val1, val2);
}

Чтобы проверить метод, попробуйте выполнить следующую команду. Это находит НОД 322328 и 122120. Результат должен быть равен 344.

int nod = GetNOD(322328, 122120); // 344

Нахождение НОД с использованием оператора модуля

Число итераций цикла в предыдущем примере кода может быть огромным. Если одно из двух значений намного больше другого, либо в начале процесса, либо позже, когда значения падают, одно и то же значение может быть вычтено много раз. Мы можем уменьшить число итераций, используя оператор модуля. Применение оператора модуля к двум значениям и замена большего значения результата приводит к одновременному применению нескольких вычитаний. Например, если два значения равны десяти и трем, три будут вычитаться три раза, чтобы уменьшить десять к одному. Используя модуль, мы получаем единицу в единственной итерации, как 10% 3 = 1.

Если результат модуля равен нулю, то найден НОД.

      public static int GetNODModul(int val1, int val2)
        {
            while ((val1!=0) && (val2!=0))
            {
                if (val1 > val2)
                    val1 %= val2;
                else
                    val2 %= val1;
            }
            return Math.Max(val1, val2);
        }

Нахождение НОД с использованием рекурсии

В окончательной версии алгоритма Евклида для получения результата используется рекурсия. Это полезно при использовании функциональных языков программирования, таких как F#. Тем не менее, я опишу его здесь, используя C# для полноты картины.

Рекурсивный метод имеет два возможных результата. Если второе значение равно нулю, первое значение будет НОД и будет возвращено. Если второе значение не равно нулю, метод вызывается снова. Новый вызов передает второе значение, которое предполагается меньшим числом, и модуль первого и второго целых чисел. Каждый вызов постепенно снижает значения до тех пор, пока не будет найден НОД. Обратите внимание, что, хотя второе значение предполагается меньшим, его может не быть. Если второе целое больше первого, первоначальный вызов заменит значения.

        public static int GetNODRecurs(int val1, int val2)
        {
            if (val2 == 0)
                return val1;
            else
                return GetNODRecurs(value2, val1 % val2);
        }


Автор этого материала – я – Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML – то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, си шарп, алгоритмы

Алгоритм Евклида – это алгоритм для поиска наибольшего общего делителя двух чисел. Алгоритм впервые описан древнегреческим математиком Евклидом.

Наибольший общий делитель (НОД) – это наибольшее число, на которое делятся заданные числа без остатка.

Алгоритм основан на том, что наибольший общий делитель пары чисел, не меняется, если из большего числа вычесть меньшее. Если повторять операцию вычитания, то в конце приходим к тому, что одно из чисел становится равным нулю, а второе является НОД.

Рекурсивная реализация поиска наибольшего общего делителя

Напишем два вспомогательных метода, которые возвращают минимальное и максимальное из двух чисел:

static int Min(int x, int y)
{
    return x < y ? x : y;
}

static int Max(int x, int y)
{
    return x > y ? x : y;
}

Нахождение НОД для двух чисел c использованием вычитания

При каждом рекурсивном вызове вычитаем из максимального числа минимальное, повторяя рекурсивные вызовы до тех пор, пока первый аргумент не будет равен нулю:

static int GCD(int a, int b)
{
    if (a == 0)
    {
        return b;
    }
    else
    {
        var min = Min(a, b);
        var max = Max(a, b);
        //вызываем метод с новыми аргументами
        return GCD(max - min, min);
    }
}

Использование оператора остатка от деления % для вычисления НОД

Для уменьшения количества рекурсивных вызовов, при вычислении, можно воспользоваться оператором остатка от деления и вместо разницы, передавать в метод остаток от деления максимального числа на минимальное.
Чтобы ускорить алгоритм, достаточно изменить знак в строке возврата предыдущего метода с “-” на “%”:

return GCD(max % min, min);

Использование остатка очень ускоряет работу алгоритма поиска НОД. К примеру для пары чисел 1013 и 65 с использованием вычитания метод вызывается 27 раз, а с остатком от деления всего 7.

Вычисление НОД в циклах

Циклическое вычисление наибольшего общего делителя с вычитанием

static int GCD(int a, int b)
{
    if (a == 0)
    {
        return b;
    }
    else
    {
        while (b != 0)
        {
            if (a > b)
            {
                a -= b;
            }
            else
            {
                b -= a;
            }
        }

        return a;
    }
}

Циклический поиск наибольшего общего делителя с остатком от деления

static int GCD(int a, int b)
{
    while (b != 0)
    {
        var temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

Программа для поиска НОД чисел

Напишем программу, в которой будем использовать один из методов рассмотренных выше:

using System;

class Program
{
    static int GCD(int a, int b)
    {
        while (b != 0)
        {
            var t = b;
            b = a % b;
            a = t;
        }
        return a;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("Алгоритм Евклида");
        Console.Write("A = ");
        var a = Convert.ToInt32(Console.ReadLine());
        Console.Write("B = ");
        var b = Convert.ToInt32(Console.ReadLine());
        Console.WriteLine("Наибольший общий делитель чисел {0} и {1} равен {2}", a, b, GCD(a, b));
        Console.ReadLine();
    }
}

Результат работы программы:

Для чисел 36 и 60 программа возвращает значение 12.

Наибольший общий делитель трех чисел

Для получения НОД для трех чисел и более чисел необходимо вызывать метод следующим образом:

var n1 = GCD(GCD(15, 30), 75); //для трех параметров результат 15
var n2 = GCD(GCD(16, 36), GCD(585, 360)); //для четырех чисел результат 1

В первом примере сначала вычисляется НОД(15, 30) = 15, потом результат вычислений передается в качестве аргумента и вычисляется НОД(15, 75) = 15.
Во втором примере вычисляются НОД(16, 36) = 4 и НОД(585, 360) = 45, а результаты передаются в метод НОД(4, 45) = 1.

Смотрите также:

“The greatest common divisor of two integers is the largest integer that evenly divides each of the two numbers. Write method Gcd that returns the greatest common divisor of two integers. Incorporate the method into an app that reads two values from the user and displays the result.”

(this is not homework, just an exercise in the book I’m using)

can you help me solve this? Here’s what I’ve got so far.

(edit – I can submit the two numbers but it won’t calculate the Gcd for me)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Greatest_Common_Divisor
{
class Program
{

    static int GetNum(string text)
    {
        bool IsItANumber = false;
        int x = 0;
        Console.WriteLine(text);

        do
        {
            IsItANumber = int.TryParse(Console.ReadLine(), out x);

        } while (!IsItANumber);

        return x;
    }
    static void Main(string[] args)
    {
        string text = "enter a number";
        int x = GetNum(text);
        text = "enter a second number";
        int y = GetNum(text);


        int z = GCD(x, y);
        Console.WriteLine(z);
    }

    private static int GCD(int x, int y)
    {
        int v = 0;
        int n = 0;

        v = GetGreatestDivisor(x, y);


        return v;

    }

    static int GetGreatestDivisor(int m, int h)
        {

            do
            {
                for (int i = m; i <= 1; i--)



                    if (m%i == 0 && h%i == 0)
                    {
                        int x = 0;
                        x = i;

                        return x;
                    }
            } while (true);
            return m;
        }

  }
}

A-Sharabiani's user avatar

A-Sharabiani

17.3k17 gold badges112 silver badges127 bronze badges

asked Aug 30, 2013 at 21:38

user2723261's user avatar

3

Here’s an implementation of the Euclidean algorithm that returns the greatest common divisor without performing any heap allocation.

You can substitute ulong for uint if needed. An unsigned type is used, as the technique does not work for signed values. If you know your a and b values are not negative, you can use long or int instead.

private static ulong GCD(ulong a, ulong b)
{
    while (a != 0 && b != 0)
    {
        if (a > b)
            a %= b;
        else
            b %= a;
    }

    return a | b;
}

This method is used in my metadata-extractor library, where it has associated unit tests.

answered Jan 20, 2017 at 14:38

Drew Noakes's user avatar

Drew NoakesDrew Noakes

298k163 gold badges677 silver badges739 bronze badges

6

Using LINQ’s Aggregate method:

static int GCD(int[] numbers)
{
    return numbers.Aggregate(GCD);
}

static int GCD(int a, int b)
{
    return b == 0 ? a : GCD(b, a % b);
}

Note: answer above borrowed from accepted answer to Greatest Common Divisor from a set of more than 2 integers.

Jim Buck's user avatar

Jim Buck

2,37523 silver badges42 bronze badges

answered Aug 30, 2013 at 21:44

Karl Anderson's user avatar

Karl AndersonKarl Anderson

34.5k12 gold badges65 silver badges80 bronze badges

3

You can try using this:

static int GreatestCommonDivisor(int[] numbers)
{
    return numbers.Aggregate(GCD);
}

static int GreatestCommonDivisor(int x, int y)
{
return y == 0 ? x : GreatestCommonDivisor(y, x % y);
}

Arsen Khachaturyan's user avatar

answered Aug 30, 2013 at 21:41

Rahul Tripathi's user avatar

Rahul TripathiRahul Tripathi

167k31 gold badges276 silver badges330 bronze badges

1

Try this:

public static int GCD(int p, int q)
{
    if(q == 0)
    {
         return p;
    }

    int r = p % q;

    return GCD(q, r);
}

answered Aug 30, 2013 at 21:50

user2623931's user avatar

Here is a simple solution.
You can use BigInteger to get the greatest common divisor. Just do not forget to add using System.Numerics; to the top of your code.

using System.Numerics;

public class Program{
    public static void Main(String[] args){
        int n1 = 1;
        int n2 = 2;

        BigInteger gcd = BigInteger.GreatestCommonDivisor(n1,n2);
        Console.WriteLine(gcd);
    }
}

Offical Documentation

ouflak's user avatar

ouflak

2,44810 gold badges44 silver badges49 bronze badges

answered Mar 1, 2022 at 17:09

CheckerPhil's user avatar

public class GCD 
{        
    public int generalizedGCD(int num, int[] arr)
    {
         int gcd = arr[0]; 

        for (int i = 1; i < num; i++) {
            gcd = getGcd(arr[i], gcd); 
        }

        return gcd; 
    }    
    public int getGcd(int x, int y) 
    { 
        if (x == 0) 
            return y; 
        return getGcd(y % x, x); 
    } 
}

answered Oct 27, 2019 at 10:54

Adil Rao's user avatar

By using this, you can pass multiple values as well in the form of array:-


// pass all the values in array and call findGCD function
    int findGCD(int arr[], int n) 
    { 
        int gcd = arr[0]; 
        for (int i = 1; i < n; i++) {
            gcd = getGcd(arr[i], gcd); 
}

        return gcd; 
    } 

// check for gcd
int getGcd(int x, int y) 
    { 
        if (x == 0) 
            return y; 
        return gcd(y % x, x); 
    } 

answered Dec 8, 2018 at 10:42

Chang's user avatar

ChangChang

4351 gold badge8 silver badges16 bronze badges

If efficiency is not a big concern this will do the job.

// gets greatest common divisor of A and B. 
var GCD=Enumerable.Range(1,Math.Min(A,B)).Last(n=>(A%n | B%n)==0);

answered Jul 24, 2020 at 15:26

Zuabros's user avatar

ZuabrosZuabros

2541 silver badge5 bronze badges

List<int> gcd = new List<int>();
int n1, n2;

bool com = false;

Console.WriteLine("Enter first number: ");
n1 = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second number: ");
n2 = int.Parse(Console.ReadLine());

for(int i = 1; i <= n1; i++)
{
    if(n1 % i == 0 && n2% i == 0)
    {
        gcd.Add(i);
    }

    if(i == n1)
    {
        com = true;
    }
}

if(com == true)
{
    Console.WriteLine("GCD of {0} and {1} is {2}.", n1, n2, gcd[gcd.Count - 1]);
}
Console.ReadLine();

pquest's user avatar

pquest

3,1313 gold badges27 silver badges40 bronze badges

answered Feb 29, 2020 at 12:30

Hulk Hogan's user avatar

int[] nums = new int[] {6,12,24,48};
int GCD(int a, int b) => b == 0 ? a : GCD(b, a % b);
int FindGCD(int[] numbers) => numbers.Aggregate(GCD);

Console.WriteLine($"List of numbers ({String.Join(',',nums)})");
Console.WriteLine($"Smallest number: {nums.Min()}");
Console.WriteLine($"Largest number: {nums.Max()}");
Console.WriteLine($"Greatest common devisor of {nums.Min()} and {nums.Max()}: {GCD(nums.Min(),nums.Max())}");
Console.WriteLine($"Aggregate common devisor of array ({String.Join(',',nums)}): {FindGCD(nums)}");

List of numbers (6,12,24,48)

Smallest number: 6

Largest number: 48

Greatest common devisor of 6 and 48: 6

Aggregate common devisor of array (6,12,24,48): 6

answered Nov 12, 2021 at 0:58

Edward Thomas's user avatar

    public class Program
{
    public static int GETGCD(int[] a)
    {
        int index = 0;
        int answer = 0;
        while (index < a.Length)
        {
            for (int x = 0; x < a.Length; x++)
            {
                if (a[x] % a[index] == 0)
                {
                    answer = a[index];
                }
                else
                {
                    answer = 0;
                    x += a.Length;
                }
            }
            if (answer == 0)
            {
                index++;
            }
            if (answer != 0)
            {
                index += a.Length;
            }

        }
        if (answer == 0)
        {
            answer = 1;
        }
        return answer;
    }

    public static void Main(string[] args)
    {
        int[] a = { 2, 3, 7, 8, 9, 10 };
        int[] b = { 2, 4, 6, 8, 10 };

        Console.WriteLine("Greatest Common Divisor of {" + String.Join(",", a.Select(i => i.ToString()).ToArray()) + "} is " + GETGCD(a));
        Console.WriteLine("Greatest Common Divisor of {" + String.Join(",", b.Select(i => i.ToString()).ToArray()) + "} is " + GETGCD(b));
    }
}

This is fully running code. Just copy and paste it. Screenshot of the output is attached.

enter image description here

Lajos Arpad's user avatar

Lajos Arpad

62.2k37 gold badges96 silver badges174 bronze badges

answered Apr 17 at 1:21

Muhammad Arslan Idrees's user avatar

using System;

//Write a function that returns the greatest common divisor (GCD) of two integers

namespace GCD_of_Two_Numbers
{
    class Program
    {
        public static void Gcd(int num1, int num2)
        {
            int[] temp1 = new int[num1];
            int[] temp2 = new int[num2];
            int[] common = new int[10];

            for(int i=2;i<num1/2;i++)
            {
                if(num1 % i ==0)
                {
                    temp1[i] = i;
                }
            }

            for (int i = 2; i < num2/2; i++)
            {
                if (num2 % i == 0)
                {
                    temp2[i] = i;
                }
            }
            int len = temp1.Length + temp2.Length;
            for(int i=0;i<len;i++)
            {
                if(temp1[i]==temp2[i])
                {
                    common[i] = temp1[i];
                }
            }

            int max_number = common[0];
            for(int i=0;i<common.Length;i++)
            {
                if(max_number < common[i])
                {
                    max_number = common[i];
                }
            }

            Console.WriteLine($"The Greatest Common Diviser is {max_number}");
        }
        
        static void Main(string[] args)
        {
            Gcd(32, 8);
        }
    }
}

Pranav Singh's user avatar

Pranav Singh

16.2k29 gold badges77 silver badges103 bronze badges

answered May 26, 2021 at 16:18

taha's user avatar

    int a=789456;


    int b=97845645;
    if(a>b)     
    {

    }
    else
    {
        int temp=0;
        temp=a;
        a=b;
        b=temp;
    }
    int x=1;
    int y=0 ;

    for (int i =1 ; i < (b/2)+1 ; i++ )
    {

        if(a%i==0)
        {
             x=i;
        }
        if(b%i==0)
        {
             y=i;
        }
        if ((x==y)& x==i & y==i & i < a)
        {
            Console.WriteLine(i);
        }

    }

answered Dec 24, 2017 at 11:26

seyed's user avatar

seyedseyed

13 bronze badges

Наибольший общий делитель

 Постановка задачи. Дано два целых положительных числа x и y. Наибольшее число, на которое делятся оба числа без остатка, называют наибольшим общим делителем (НОД). Наверно, это вам известно из школьного курса математики. Зачем он нужен? Например, для упрощения дробей: 26/39=2/3, т.к. НОД(x,y)=13. Или для нахождения простых чисел, которые используются в алгоритмах защиты информации.

Вариант решения. Примерно 23 века назад, когда  люди еще могли обходиться без компьютеров, известный вам основатель геометрии Евклид придумал удивительный по простоте алгоритм нахождения НОД без использования операции деления. Он состоит в сравнении двух чисел и операциях вычитания одного числа из другого. Другой, более очевидный (всегда ли тому учат в школе?) алгоритм состоит в разложении каждого числа на простые множители и последующем анализе общих множителей – попробуйте его запрограммировать самостоятельно.

Реализация. Придерживаясь принципа проектирования «сверху-вниз», объявим в классе Program метод  static int НОД(int x, int y), а ввод и вывод результата выполним в Main(). Тогда:

// Нахождение наибольшего общего делителя (НОД) двух целых чисел
// Алгоритм Евклида,  300 год до н. э.  -  Функция НОД(x,y)
using System;
namespace НаибольшийОбщийДелитель
{
    class Program
    {
        static void Main(string[] args)
        {
            int x, y;
            Console.Write("x= ");
            x = Convert.ToInt32(Console.ReadLine());
            Console.Write("y= ");
            y = Convert.ToInt32(Console.ReadLine());
            Console.WriteLine("НОД = {0}",НОД(x,y));
            Console.ReadKey();
        }
        //  Функция НОД(x,y)
        static int НОД(int x, int y)
        {
            while (x != y)
            {
                if (x > y)
                    x = x - y;
                else
                    y = y - x;
            }
            return x;
        }
    }
}

Результат:

2195

Замечание. При разработке алгоритмов решения массовых (часто выполняющихся при различных исходных данных) задач имеет значение их эффективность. Под этим понимаются время выполнения и объем требуемой памяти. С этой точки зрения алгоритм Евклида является образцом для программиста.

Далее планируется дополнять этот раздел новыми примерами, в том числе предложенными вами

Вам предлагаются задачи для самостоятельного решения с использованием навыков, приобретаемых при творческом освоении основ языка C#.


NEW: Наш Чат, в котором вы можете обсудить любые вопросы, идеи, поделиться опытом или связаться с администраторами.


Помощь проекту:

Добавить комментарий