算法基础学习笔记——⑭欧拉函数\快速幂\扩展欧几里得算法\中国剩余定理

news2024/9/28 11:12:27

博主:命运之光
专栏:算法基础学习

在这里插入图片描述

目录

✨欧拉函数

🍓求欧拉函数 :

🍓筛法求欧拉函数 :

✨快速幂

✨扩展欧几里得算法

✨中国剩余定理


前言:算法学习笔记记录日常分享,需要的看哈O(∩_∩)O,感谢大家的支持!


✨欧拉函数

在C语言中,可以使用算法来计算欧拉函数(Euler's Totient Function)。欧拉函数,也被称为φ函数,用于计算小于或等于给定数字n的正整数中与n互质的数的个数。

🍓以下是一个用C语言编写的计算欧拉函数的示例代码:

#include <stdio.h>

int gcd(int a, int b) {
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

int eulerTotient(int n) {
    int count = 0;
    for (int i = 1; i <= n; i++) {
        if (gcd(n, i) == 1) {
            count++;
        }
    }
    return count;
}

int main() {
    int n;
    printf("Enter a number: ");
    scanf("%d", &n);
    int result = eulerTotient(n);
    printf("Euler's Totient Function of %d is %d\n", n, result);
    return 0;
}

在上述代码中,gcd函数用于计算两个数的最大公约数。eulerTotient函数遍历从1到n的所有数字,检查它们是否与n互质(即它们的最大公约数为1),并统计互质的数字的个数。最后,程序输出计算得到的欧拉函数值。可以运行上述代码,输入一个正整数,程序将计算并输出该数的欧拉函数值。


表示:\Phi(n)

定义:1~n中与n互质的数的个数

🍓求欧拉函数 :

int phi(int x)
{
     int res = x;
     for (int i = 2; i <= x / i; i ++ )
         if (x % i == 0)
         {
             res = res / i * (i - 1);
             while (x % i == 0) x /= i;
         }
     if (x > 1) res = res / x * (x - 1);
     return res;
}

🍓筛法求欧拉函数 :

int primes[N], cnt; // primes[]存储所有素数,cnt存储每个素数的下标
int euler[N]; // 存储每个数的欧拉函数
bool st[N]; // st[x]存储x是否被筛掉
void get_eulers(int n)
{
     euler[1] = 1;
     for (int i = 2; i <= n; i ++ )
     {
         if (!st[i])
         {
             primes[cnt ++ ] = i;
             euler[i] = i - 1;
         }
         for (int j = 0; primes[j] <= n / i; j ++ )
         {
             int t = primes[j] * i;
             st[t] = true;
             if (i % primes[j] == 0)
             {
                 euler[t] = euler[i] * primes[j];
                 break;
             }
             euler[t] = euler[i] * (primes[j] - 1);
         }
     }
}

✨快速幂

在C语言中,可以使用快速幂算法(Fast Exponentiation)来高效计算幂运算。快速幂算法通过将指数分解为二进制形式,从而减少了乘法和幂运算的次数,从而提高了计算效率。

🍓以下是一个用C语言编写的快速幂算法的示例代码:

#include <stdio.h>
long long fastExponentiation(int base, int exponent) {
    long long result = 1;
    while (exponent > 0) {
        if (exponent % 2 == 1) {
            result *= base;
        }
        base *= base;
        exponent /= 2;
    }
    return result;
}
int main() {
    int base, exponent;
    printf("Enter the base: ");
    scanf("%d", &base);
    printf("Enter the exponent: ");
    scanf("%d", &exponent);
    long long result = fastExponentiation(base, exponent);
    printf("%d raised to the power of %d is %lld\n", base, exponent, result);
    return 0;
}

在上述代码中,fastExponentiation函数使用了迭代的方式来计算幂运算。它首先将结果初始化为1,并进入循环。在每次循环中,它检查指数的最低位(通过取模2),如果最低位为1,则将结果乘以当前的基数。然后,将基数平方,并将指数除以2。重复这个过程,直到指数变为0,然后返回计算得到的结果。可以运行上述代码,输入一个基数和指数,程序将计算并输出幂运算的结果。请注意,由于幂运算的结果可能非常大,因此将结果的数据类型设置为long long来处理大整数。


✨扩展欧几里得算法

在C语言中,可以使用扩展欧几里得算法(Extended Euclidean Algorithm)来求解两个整数的最大公约数(最大公因数),并且同时计算出满足贝祖等式(Bézout's identity)的两个整数系数。

🍓以下是一个用C语言编写的扩展欧几里得算法的示例代码:

#include <stdio.h>
int extendedEuclidean(int a, int b, int *x, int *y) {
    // 初始情况
    if (a == 0) {
        *x = 0;
        *y = 1;
        return b;
    }
    int x1, y1;
    int gcd = extendedEuclidean(b % a, a, &x1, &y1);

    // 更新x和y
    *x = y1 - (b / a) * x1;
    *y = x1;
    return gcd;
}
int main() {
    int a, b;
    printf("Enter two numbers: ");
    scanf("%d %d", &a, &b);
    int x, y;
    int gcd = extendedEuclidean(a, b, &x, &y);
    printf("GCD: %d\n", gcd);
    printf("Coefficients (x, y): (%d, %d)\n", x, y);
    return 0;
}

在上述代码中,extendedEuclidean函数使用递归的方式来实现扩展欧几里得算法。它将两个整数a和b作为输入,并返回它们的最大公约数。同时,它通过指针参数x和y返回满足贝祖等式的两个整数系数。

在函数中,我们首先处理初始情况,当a为0时,最大公约数为b,系数x为0,系数y为1。否则,我们递归调用函数,将b mod a和a作为新的输入,并获取递归返回的最大公约数、系数x1和系数y1。

然后,我们使用贝祖等式的推导来更新系数x和系数y:x = y1 - (b / a) * x1,y = x1。

最后,我们在main函数中接受用户输入的两个整数a和b,并调用extendedEuclidean函数来计算最大公约数和系数。然后,我们输出最大公约数和系数的结果。

你可以运行上述代码,输入两个整数,程序将计算并输出最大公约数和满足贝祖等式的系数。


扩展欧几里得算法 :

✨中国剩余定理

在C语言中,可以使用中国剩余定理(Chinese Remainder Theorem)来求解一组同余方程组的解。中国剩余定理是一种在模数互质的情况下求解同余方程组的有效方法。

🍓以下是一个用C语言编写的中国剩余定理算法的示例代码:

#include <stdio.h>
int extendedEuclidean(int a, int b, int *x, int *y) {
    // 初始情况
    if (a == 0) {
        *x = 0;
        *y = 1;
        return b;
    }
    int x1, y1;
    int gcd = extendedEuclidean(b % a, a, &x1, &y1);
    // 更新x和y
    *x = y1 - (b / a) * x1;
    *y = x1;
    return gcd;
}
int modInverse(int a, int m) {
    int x, y;
    int gcd = extendedEuclidean(a, m, &x, &y);
    if (gcd != 1) {
        printf("Inverse doesn't exist\n");
        return -1;
    }
    int result = (x % m + m) % m;
    return result;
}
int chineseRemainder(int num[], int rem[], int n) {
    int prod = 1;
    for (int i = 0; i < n; i++) {
        prod *= num[i];
    }
    int result = 0;
    for (int i = 0; i < n; i++) {
        int pp = prod / num[i];
        int inv = modInverse(pp, num[i]);
        result += rem[i] * pp * inv;
    }
    result %= prod;
    return result;
}
int main() {
    int num[10], rem[10], n;
    printf("Enter the number of equations: ");
    scanf("%d", &n);
    printf("Enter the values of equations (num and rem):\n");
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &num[i], &rem[i]);
    }
    int result = chineseRemainder(num, rem, n);
    printf("Solution: %d\n", result);
    return 0;
}

在上述代码中,我们定义了三个函数:extendedEuclidean用于计算最大公约数和系数,modInverse用于计算模反元素(模逆元),chineseRemainder用于求解同余方程组。

extendedEuclidean和modInverse函数的实现与之前提到的扩展欧几里得算法的示例代码中的函数相同。

chineseRemainder函数首先计算所有模数的乘积,然后使用循环计算每个同余方程的乘积、模逆元和余数,最后将所有结果求和。最终,通过对乘积取模得到最小非负整数解。

在main函数中,我们首先接受用户输入的同余方程个数和每个方程的模数和余数。然后,调用chineseRemainder函数来计算同余方程组的解,并输出值。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/587043.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python中的倒序输出方法

Python中的倒序输出方法 在Python中&#xff0c;倒序输出是一个经常用到的操作。倒序输出可以用于字符串、列表、元组等数据类型&#xff0c;帮助我们更方便地处理数据。 字符串的倒序输出 对于字符串&#xff0c;我们可以使用字符串切片的方法倒序输出。例如&#xff0c;我…

十二、Vben之Vue3+vite跨域代理地址实现

在vue2中使用proxy进行跨域的原理是:将域名发送给本地的服务器(启动vue项目的服务,loclahost:8080),再由本地的服务器去请求真正的服务器。 代码如下: 1.在proxy中设置要访问的地址,并重写/api为空的字符串,这里如果不重写,会相当于在代理的地址上默认加了/api,所以…

chatgpt赋能python:Python中安装jieba分词器

Python中安装jieba分词器 介绍 中文分词是文本挖掘中非常重要的一个环节&#xff0c;而jieba是Python中最受欢迎的中文分词器之一。jieba分词器是基于汉语词汇库进行分词&#xff0c;并支持多种分词模式&#xff0c;可以满足不同场景的分词需求。 本文将介绍如何在Python环境…

chatgpt赋能python:Python中如何安装pip

Python中如何安装pip 什么是pip&#xff1f; pip&#xff0c;全称pip installs packages&#xff0c;是一个Python包管理工具&#xff0c;可以用来安装、升级和卸载Python包。它广泛地应用于Python社区&#xff0c;可以帮助Python开发者快速地获取和分享Python代码。 安装pi…

对比 RS232,RS422,RS485

对比 RS232,RS422,RS485 首先&#xff0c; 串口、UART口、COM口、RJ45网口、USB口是指的物理接口形式(硬件)。TTL、RS-232、RS-485、RS-422是指的电平标准(电信号)。 RS232,RS422,RS485 对比表格 通信标准RS-232RS-422RS-485工作方式单端差分差分通信线数量4 地线52 地线3节…

《深入理解计算机系统(CSAPP)》第5章 优化程序性能 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习CSAPP时的个人笔记&#xff0c;分享出来与大家学习交流&#xff0c;目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记&#xff0c;在复习回看时发现部分内容存在一些小问题&#xff0c;因时间紧张来不及再次整理…

Java中如何判断是否为闰年

✨博主&#xff1a;命运之光 ✨专栏&#xff1a;Java经典程序设计 目录 ✨介绍 &#x1f353;引言&#xff1a;闰年的定义和在编程中的应用 &#x1f353;目的&#xff1a;介绍如何使用Java编写一个函数来判断年份是否为闰年 ✨闰年的条件 ✨提供数学原理和背景知识 &…

软考A计划-试题模拟含答案解析-卷十一

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

牛客网刷题学习SQL(三)

SQL23 统计每个学校各难度的用户平均刷题数 首先分析题目&#xff1a; 想要计算一些参加了答题的不同学校、不同难度的用户平均答题量 不同学校&#xff1a; group by 学校 不同难度&#xff1a; group by 难度 平均答题量&#xff1a;注意用户去重&#xff0c;还有指定questi…

python:绘制GAM非线性回归

作者&#xff1a;CSDN _养乐多_ 本文将介绍使用python语言绘制广义线性模型&#xff08;Generalized Additive Model&#xff0c;GAM&#xff09;非线性回归散点图和拟合曲线。并记录了计算RMSE、ubRMSE、R2、Bias的代码。 文章目录 一、GAM非线性回归详解二、代码三、计算RM…

华为OD机试真题B卷 Java 实现【统计字符】,附详细解题思路

一、题目描述 输入一行字符&#xff0c;分别统计出包含英文字母、空格、数字和其它字符的个数。 数据范围&#xff1a;输入的字符串长度满足 1 \le n \le 1000 \1≤n≤1000 。 二、输入描述 输入一行字符串&#xff0c;可以有空格。 三、输出描述 统计其中英文字符&#…

chatgpt赋能python:Python中如何空一行

Python中如何空一行 在Python编程中&#xff0c;许多情况下我们需要在输出内容的时候空出一行。今天我们将介绍如何在Python中实现空一行的方法。 方法1&#xff1a;使用print()函数 在Python中&#xff0c;我们可以使用print()函数打印空行。我们只需在print()函数中输入两…

并发编程 原子性 可见性 有序性

并发编程的三个重要特性 原子性所谓原子性是指在一次的操作或者多次操作中&#xff0c;要么所有的操作全部都得到了执行并且不会受到任何因素的干扰而中断&#xff0c;要么所有的操作都不执行。可见性可见性是指&#xff0c;当一个线程对共享变量进行了修改&#xff0c;那么另…

chatgpt赋能python:Python中如何合并列表-详细教程

Python中如何合并列表 - 详细教程 在Python编程中&#xff0c;有时候需要把两个或多个列表合并成一个单一的列表&#xff0c;以便更好地进行数据处理。Python中有几种方法可以实现列表合并&#xff0c;本文将介绍其中的三种方法。 1. 使用“”符号 最常见的方法是使用“”符…

InsCode AI 创作助手:源于 CSDN 的 AI 创作助手,不一样的创作体验

文章目录 &#x1f4cb;前言&#x1f3af;AIGC 时代的产物&#x1f3af;InsCode AI 创作助手体验&#x1f3af;一些感受和建议&#x1f9e9;感受&#x1f9e9;建议&#xff08;个人看法&#xff09; &#x1f4dd;最后 &#x1f4cb;前言 是的没错&#xff0c;CSDN AI 写作助手…

Vue组件化开发

1. 认识组件 1.1 基础示例 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widt…

STM32CubeIDE + HAL + STM32f103C8T6 系列教程1 ---板载PC13LED闪烁

STM32CubeIDE HAL STM32f103C8T6 系列教程1 --- 板载PC13LED闪烁 引言硬件关于开发板[^2]控制器内置存储器原理图 硬件连线硬件连接表硬件连线图 软件STM32CubeIDE下载及安装Stm32CubeIDE设置补全快捷键和主题新建一个工程选择开发板核心芯片型号设置工程相关参数STM32CubeMX…

最热门高效的Node.JS开源第三方开发库和特点(持续更新......)

目录 1. Express 2. Socket.io 3. Mongoose 4. Passport 5. Async 6. PM2 7. Nodemailer 8. Request 9. Cheerio 10. Lodash 11. Bluebird 12. Winston 13. Socket.io-client 14. Node-sass 15. Moment 16. Gulp 17. Grunt 18. Chai 19. Sinon 20. Nodemon…

Java线程之间如何通信的,有哪些方式?

线程之间的通信方式主要有以下几种&#xff1a; 共享变量&#xff1a;线程之间可以通过共享变量来进行通信。不同的线程可以共享同一个变量&#xff0c;并在变量上进行读写操作。需要注意的是&#xff0c;共享变量可能会引发线程安全问题&#xff0c;需要通过同步机制来确保线程…

chatgpt赋能Python-python中怎么导入numpy

介绍 Python是一种广泛使用的编程语言&#xff0c;具有许多内建功能和模块&#xff0c;让开发者能够快速地编写代码。然而&#xff0c;虽然能够实现许多计算&#xff0c;但是原始Python本身并不足够处理各种科学和数字计算上需要的高效性&#xff0c;因此numpy这个开源的Pytho…