【c语言】循环2

考点整合

A + B 问题

分离一个整数每一位

  • 从后往前
  • 从前往后→
    • 字符数组(字符串) / 看成一堆字符
    • 栈(先入后出) → 递归

while → 循环版的if (while循环的直接应用 → 模拟)

gcd 和 lcm

递推和递归

  • 递推往往用迭代(循环)来实现
  • 讲从前往后分离整数的递归写法

打擂法 求max, min

判断素数

  • O (n) → 分离因子的快捷的求法
  • O (sqrt(n))

打印素数表

数列求和、斐波那契数列(递推)

判断平方数

最大公约数gcd 和 最小公倍数lcm

实现方式

  • 递推
  • 递归
  • c++库函数 __gcd()

求gcd(a, b) → 辗转相除法

  1. 除数作为新的被除数, 原来的被除数 % 除数的结果作为新的除数

  2. 看除数是否为0,如果除数不为0,就循环上述操作

  3. 如果除数为0,gcd(a, b) = a;


被除数 除数
4      16
16     4    
4      0

2      7
7      2
2      1
1      0



    /*
    
    a = 4    b = 16

    a = 16    b = 16
              
    a = 16   b = 0

    */


/*递推实现*/

//错误示范
while(b)  //错误示范 → a的值被b的值覆盖掉了, 而我们需要用原来的a的值
{
    a = b;
    b = a % b;
}

//正确示范
int gcd(int a, int b) 
{
    while(b)
    {
        int r = a; //暂存原来a的值
        a = b;
        b = r % b;
    }
    return a;
}


/*递归实现*/

递归 → 函数里面, 函数自己调用自己

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


int gcd(int a, int b)
{
    return !b ? a : gcd(b, a % b);
}



/*c++库函数 __gcd(x, y)*/

#include <algorithm>

int a = 5, b = 10;

int ans = __gcd(a, b);

printf("%d", ans);


递推与递归

  • 一般指的是函数中的两种实现的方式
  • 递归 → 函数自己调用自己

斐波那契数列 → f(1) = 1, f(2) = 1, f(n) = f(n - 1) + f(n - 2); 


回溯 → 原问题的解
n = 5
               f(5) 5
        f(3) 2           f(4) 3
    f(1)   f(2)     f(2)1    f(3) 2
                         f(1)  f(2)


缩小规模               ↓

回溯+合并子问题的答案   ↑

f(1) = 1;
f(2) = 1;

输入n
f(n) = f(n - 1) + f(n - 2)


n = 5
int Fibonacci(int n)
{
    if(n == 1 || n == 2) return 1; //递归边界
    return Fibonacci(n - 1) + Fibonacci(n - 2); //缩小规模的式子(递归表达式)
}


int main()
{
    int n;
    scanf("%d", &n);
    int ans = Fibonacci(n);

    printf("%d", ans);
    return 0;
}
//系统栈


int n;
scanf
int ans = 0;
int a = 1, b = 1;

int f[1] = 1;
int f[2] = 1;


for(int i = 3; i <= n; i++)
{  
    f[i] = f[i - 1] + f[i - 2]; 
}

f[n];
  • 从前往后分离整数之栈写法

#include <stdio.h>

const int N = 10010;

int stk[N]; //整型数组来模拟一个栈

int tt; //代表栈顶元素的位置


void push(int x)
{
    stk[++tt] = x;
}

int top()
{
    return stk[tt];
}

void pop()
{
    tt--;
}

int is_empty()
{
    if(tt == 0) return 1;
    else return 0;
}
void get_dig(int x)
{

    while(x)
    {
        push(x % 10);
        x /= 10;
    }

    while(!is_empty())
    {
        printf("%d ", top());
        pop();
    }
        
}
int main()
{
    int n;
    scanf("%d", &n);

    get_dig(n);
    return 0;
}


打擂法

设置一个初始值

  • 可以用第一个元素作为初始值
  • 求max, max = 非常小的数
  • 求min, min = 非常大的数
//求n个数的最大值和最小值

#include <stdio.h>

int main()
{
    int n;
    scanf("%d", &n);

    int tmp;
    int max, min;
    scanf("%d", &tmp);
    max = tmp;
    min = tmp;

    int max_id = 0;
    int min_id = 0;

    for(int i = 1; i < n; i++)
    {
        int x; //当前读入的元素是x
        scanf("%d", &x);

        if(x > max) 
        {
            max = x;
            max_id = i;
        }
        if(x < min) 
        {
            min = x;
            min_id = i;
        }
    }

    printf("%d %d", max, min);
    return 0;
}

int main()
{
    int min = 0x3f3f3f3f;
    
    int max = -0x3f3f3f3f;

    for(int i = 0; i < n; i++)
    {
        if(x > max) max = x;
        if(x < min) min = x;
    }

    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值