栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

第六章 函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第六章 函数

目录

1.基础知识2.练习题

2.1 n的阶乘2.2 x和y的最大值2.3 最大公约数2.4 交换数值2.5 打印数字2.6 打印矩阵2.7 递归求阶乘2.8 递归求斐波那契数列2.9 绝对值2.10 两个数的和2.11 区间求和2.12 最小公倍数2.13 复制数组2.14 打印字符串2.15 数组翻转2.16 数组去重2.17 数组排序2.18 跳台阶2.19 走方格2.20 排列

1.基础知识

1.函数调用自己叫递归
2.函数数组传递属于引用传递,也就是说,修改函数数组里的数值会发生改变;
3.函数在传二维数组的时候,列数一定要写。因为二维数组在存储的时候是连续的一段空间,数组名相当于行指针(行信息),如果不告诉计算机列数(列信息),那和一维数组没有什么区别。如果告诉了,计算机就会知道面对一段连续的数组怎么划分行和列。

2.练习题 2.1 n的阶乘

输入一个整数 n,请你编写一个函数,int fact(int n),计算并输出 n 的阶乘。

输入格式
共一行,包含一个整数 n。

输出格式
共一行,包含一个整数表示 n 的阶乘的值。

数据范围
1≤n≤10
输入样例:
3
输出样例:
6

#include 
using namespace std;

int fact(int n)
{
    if(n == 1) return 1;
    else
    {
        return n * fact(n - 1);
    }
}

int main()
{
    int n;
    cin >> n;
    int res = fact(n);
    cout << res << endl;
    return 0;
}
2.2 x和y的最大值

输入两个整数 x 和 y,请你编写一个函数,int max(int x, int y),计算并输出 x 和 y 的最大值。

输入格式
共一行,包含两个整数 x 和 y。

输出格式
共一行,包含一个整数,表示两个数中较大的那个数。

数据范围
−100≤x,y≤100
输入样例:
3 6
输出样例:
6

#include 
using namespace std;

int max(int x, int y)
{
    if(x >= y) return x;
    else return y;

}

int main()
{
    int x, y;
    cin >> x >> y;

    cout << max(x, y) << endl;
    return 0;
}
2.3 最大公约数

输入两个整数 a 和 b,请你编写一个函数,int gcd(int a, int b), 计算并输出 a 和 b 的最大公约数。

输入格式
共一行,包含两个整数 a 和 b。

输出格式
共一行,包含一个整数,表示 a 和 b 的最大公约数。

数据范围
1≤a,b≤1000
输入样例:
12 16
输出样例:
4

//求最大公约数有个简便的方法,叫转展相除法
#include 
using namespace std;

int gcd(int a, int b);

int main()
{
    int a, b;
    cin >> a >> b;
    
    cout << gcd(a, b) << endl;
    
    return 0;
}

int gcd(int a, int b)
{
    int tmp;
    if(a >= b) tmp = b;
    else tmp = a;
    
    for(int i = tmp; i > 0; i --)
    {
        if(a % i == 0&& b % i == 0) return i;
        else continue;
    }
}
2.4 交换数值

输入两个整数 x 和 y,请你编写一个函数,void swap(int &x, int &y), 交换两个整数的数值并输出交换后的 x 和 y。

输入格式
共一行,包含两个整数 x 和 y。

输出格式
共一行,包含交换后的 x 和 y。

数据范围
1≤x,y≤100
输入样例:
3 5
输出样例:
5 3

#include 
using namespace std;

void swap(int &x, int &y)
{
    int tmp;
    tmp = x;
    x = y;
    y = tmp;
    return;
}

int main()
{
    int x, y;
    cin >> x >> y;
    
    swap(x, y);
    cout << x << " " << y;
    return 0;
}
2.5 打印数字

输入一个长度为 n 的数组 a 和一个整数 size,请你编写一个函数, void print(int a[], int size), 打印数组 a 中的前 size 个数。

输入格式
第一行包含两个整数 n 和 size。

第二行包含 n 个整数 a[i],表示整个数组。

输出格式
共一行,包含 size 个整数,表示数组的前 size 个数。

数据范围
1≤n≤1000,
1≤size≤n,

输入样例:
5 3
1 2 3 4 5
输出样例:
1 2 3

#include 
using namespace std;

void print(int a[], int size)
{
    for(int i = 0; i < size; i ++)
    {
        cout << a[i] << " ";
    }
}

int main()
{
    int n, size;
    cin >> n >> size;
    
    int a[n];
    for(int i = 0; i < n; i ++) cin >> a[i];
    
    print(a, size);
    return 0;
}
2.6 打印矩阵

给定一个 row×col 的二维数组 a,请你编写一个函数,void print2D(int a[][N], int row, int col),打印数组构成的 row 行,col 列的矩阵。

注意,每打印完一整行需要输出一个回车。

输入格式
第一行包含两个整数 row,col。

接下来 row 行,每行包含 col 个整数,表示完整二维数组 a。

输出格式
共 row 行,每行 col 个整数,表示打印出的矩阵。

数据范围
1≤row≤100,
1≤col≤100
输入样例:
3 4
1 3 4 5
2 6 9 4
1 4 7 5
输出样例:
1 3 4 5
2 6 9 4
1 4 7 5

#include 
using namespace std;

int a[100][100];

void print2D(int a[][100], int row, int col)
{
    for(int i = 0; i < row; i ++)
    {
        for(int j = 0; j < col; j ++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
}

int main()
{
    int row, col;
    
    cin >> row >> col;
    for(int i = 0; i < row; i ++)
    {
        for(int j = 0; j < col; j ++)
        {
            cin >> a[i][j];   
        }
    }
    
    print2D(a, row, col);
    return 0;
}
2.7 递归求阶乘

请使用递归的方式求 n 的阶乘。

输入格式
共一行,包含一个整数 n。

输出格式
共一行,包含一个整数,表示 n 的阶乘的值。

数据范围
1≤n≤10
输入样例:
3
输出样例:
6

#include 
using namespace std;

int fact(int n)
{
    if(n == 1) return 1;
    else return n * fact(n - 1);
}

int main()
{
    int n;
    cin >> n;
    cout << fact(n) << endl;
    return 0;
}
2.8 递归求斐波那契数列

请使用递归的方式求斐波那契数列的第 n 项。

斐波那契数列:1,1,2,3,5…,这个数列从第 3 项开始,每一项都等于前两项之和

输入格式
共一行,包含整数 n。

输出格式
共一行,包含一个整数,表示斐波那契数列的第 n 项。

数据范围
1≤n≤30
输入样例:
4
输出样例:
3

//这是循环的写法
#include 
using namespace std;
int a[30];

int cal(int a[])
{
    for(int i = 0; i < 30; i ++)
    {
        if(i == 0 || i == 1) a[i] = 1;    
        else a[i] = a[i - 1] + a[i - 2];
    }
    
    return 0;
}

int main()
{
    int n;
    cin >> n;
    cal(a);
    
    cout << a[n - 1] << endl;
    return 0;
}
//这是用递归的方式写出来的
#include 
using namespace std;
int a[30];

int cal(int n)
{
    if(n == 1 || n == 2) return 1;
    else return (cal(n - 1) + cal(n - 2));
}

int main()
{
    int n;
    cin >> n;
    
    cout << cal(n) << endl;
    return 0;
}


递归的图示,类似于树的深度优先遍历,可以从图中看出f(2)和f(1)重复算很多次,效率比较低。

2.9 绝对值

输入一个整数 x,请你编写一个函数,int abs(int x),输出 x 的绝对值。

输入格式
共一行,包含一个整数 x。

输出格式
共一行,包含 x 的绝对值。

数据范围
−100≤x≤100
输入样例:
-3
输出样例:
3

#include 
using namespace std;

int abs(int x)
{
    if(x < 0) return -x;
    return x;
    
}

int main()
{
    int x;
    cin >> x;
    
    cout << abs(x) << endl;
    return 0;
}
2.10 两个数的和

输入两个浮点数 x 和 y,请你编写一个函数,double add(double x, double y),计算并输出 x 与 y 的和。

输入格式
共一行,包含两个浮点数 x 和 y。

输出格式
共一行,包含一个浮点数,表示两个数的和,结果保留 2 位小数。

数据范围
−1000≤x,y≤1000
输入样例:
1.11 2.22
输出样例:
3.33

#include 
using namespace std;

double add(double x, double y)
{
    return x + y;    
}

int main()
{
    double x, y;
    cin >> x >> y;
    printf("%.2lf", add(x, y));
    return 0;
}
2.11 区间求和

输入两个整数 l 和 r,请你编写一个函数,int sum(int l, int r),计算并输出区间 [l,r] 内所有整数的和。

输入格式
共一行,包含两个整数 l 和 r。

输出格式
共一行,包含一个整数,表示所求的和。

数据范围
1≤l≤r≤1000
输入样例:
3 5
输出样例:
12

#include 
using namespace std;

int sum(int l, int r)
{
    return (l + r) * (r - l + 1) / 2;    
}

int main()
{
    int l, r;
    cin >> l >> r;
    
    cout << sum(l, r) << endl;
    return 0;
}
2.12 最小公倍数

输入两个整数 a 和 b,请你编写一个函数,int lcm(int a, int b),计算并输出 a 和 b 的最小公倍数。

输入格式
共一行,包含两个整数 a 和 b。

输出格式
共一行,包含一个整数,表示 a 和 b 的最小公倍数。

数据范围
1≤a,b≤1000
输入样例:
6 8
输出样例:
24

#include 
using namespace std;

int lcm(int a, int b)
{
    for(int i = 1; i <= a * b; i ++)
    {
        if(i % a == 0 && i % b == 0) return i;
    }
}

int main()
{
    int a, b;
    cin >> a >> b;
    
    cout << lcm(a, b) << endl;
    return 0;
}
2.13 复制数组

给定两个数组 a 和 b 以及一个整数 size,请你编写一个函数,void copy(int a[], int b[], int size),将 a 数组中的前 size 个数字,复制到 b 数组中。

复制完成后,输出 b 数组。

输入格式
第一行包含整数 n,m,size,分别表示 a 数组的长度,b 数组的长度以及整数 size。

第二行包含 n 个整数,表示数组 a。

第三行包含 m 个整数,表示数组 b。

输出格式
共一行,包含 m 个整数,表示复制完成后的数组 b。

数据范围
1≤n≤m≤100,
1≤size≤n
输入样例:
3 5 2
1 2 3
4 5 6 7 8

//手动实现
#include 
using namespace std;
int a[100], b[100];

void input(int n, int m)
{
    for(int i = 0; i < n; i ++) cin >> a[i];
    for(int i = 0; i < m; i ++) cin >> b[i];
}

void copy(int a[], int b[], int size)
{
    for(int i = 0; i < size; i ++)
    {
        b[i] = a[i];
    }
}

void output(int m)
{
    for(int i = 0; i < m; i ++) cout << b[i] << " ";    
}

int main()
{
    int n, m, size;
    cin >> n >> m >> size;
    
    input(n, m);
    copy(a, b, size);
    output(m);
    return 0;
}
//方法二:memcpy函数的实现
#include 
#include 
using namespace std;
int a[100], b[100];

void input(int n, int m)
{
    for(int i = 0; i < n; i ++) cin >> a[i];
    for(int i = 0; i < m; i ++) cin >> b[i];
}

void copy(int a[], int b[], int size)
{
    memcpy(b, a, size * 4);
}

void output(int m)
{
    for(int i = 0; i < m; i ++) cout << b[i] << " ";    
}

int main()
{
    int n, m, size;
    cin >> n >> m >> size;
    
    input(n, m);
    copy(a, b, size);
    output(m);
    return 0;
}
2.14 打印字符串

给定一个字符串,请你编写一个函数,void print(char str[]),将这个字符串打印出来。

输入格式
共一行,包含一个字符串。

输出格式
共一行,表示打印出的字符串。

数据范围
1≤字符串长度≤100
输入样例:
I love AcWing.
输出样例:
I love AcWing.

#include 
using namespace std;

char a[110];

void print(char str[])
{
    puts(str);
}
int main()
{
//fgets函数容易多读入一个回车
    cin.getline(a, 110);
    print(a);
    return 0;
}
2.15 数组翻转

给定一个长度为 n 的数组 a 和一个整数 size,请你编写一个函数,void reverse(int a[], int size),实现将数组 a 中的前 size 个数翻转。

输出翻转后的数组 a。

输入格式
第一行包含两个整数 n 和 size。

第二行包含 n 个整数,表示数组 a。

输出格式
共一行,包含 n 个整数,表示翻转后的数组 a。

数据范围
1≤size≤n≤1000,
1≤a[i]≤1000
输入样例:
5 3
1 2 3 4 5
输出样例:
3 2 1 4 5

#include 
using namespace std;

const int N = 1010;
int a[N];

void reverse(int a[], int size)
{
    for(int i = 0; a[i]; i ++)
    {
        if(i >= size) cout << a[i] << " ";
        else cout << a[size - (i + 1)] << " ";
        
    }
}

int main()
{
    int n, size;
    cin >> n >> size;
    
    for(int i = 0; i < n; i ++) cin >> a[i];
    
    reverse(a, size);
    return 0;
}
//一种思路比较巧的做法
#include 
using namespace std;

const int N = 1010;
int a[N];

void reverse(int a[], int size)
{
    for(int i = 0, j = size - 1; i < j; i ++, j --) swap(a[i], a[j]);
}

int main()
{
    int n, size;
    cin >> n >> size;
    
    for(int i = 0; i < n; i ++) cin >> a[i];
    
    reverse(a, size);
    
    for(int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}
2.16 数组去重

给定一个长度为 n 的数组 a,请你编写一个函数:

int get_unique_count(int a[], int n); // 返回数组前n个数中的不同数的个数
输入格式
第一行包含一个整数 n。

第二行包含 n 个整数,表示数组 a。

输出格式
共一行,包含一个整数表示数组中不同数的个数。

数据范围
1≤n≤1000,
1≤ai≤1000。

输入样例:
5
1 1 2 4 5
输出样例:
4

注意:本题的重复数字计算方法是把数组分成两部分,前n个数和剩下的数。计算前n个数重复的数加上剩下的数(剩下的数不统计重复)。不是整个数组计算重复的数。

#include 
using namespace std;
const int N = 1000;
int a[N];
int get_unique_count(int a[], int n)
{
    int sum = 0;
    for(int i = 0; a[i]; i ++) sum ++;
    
    int tmp = 0;
    for(int i = 0; i < n; i ++)
    {
        for(int j = 0; j < i; j ++)
        {
            if(a[i] == a[j])
            {
                tmp ++;
                break;
            }
        }
    }

    return sum - tmp;
}

int main()
{
    int n;                                                                                                                                          
    cin >> n;
    
    int k = 0;
    while(cin >> a[k]) k ++;
    
    cout << get_unique_count(a, n) << endl;
    return 0;
}
2.17 数组排序

给定一个长度为 n 的数组 a 以及两个整数 l 和 r,请你编写一个函数,void sort(int a[], int l, int r),将 a[l]∼a[r] 从小到大排序。

输出排好序的数组 a。

输入格式
第一行包含三个整数 n,l,r。

第二行包含 n 个整数,表示数组 a。

输出格式
共一行,包含 n 个整数,表示排序完成后的数组 a。

数据范围
0≤l≤r 输入样例:
5 2 4
4 5 1 3 2
输出样例:
4 5 1 2 3

//冒泡排序
#include 
#include 
using namespace std;

void sort(int a[], int l, int r)
{
    for(int i = l; i <= r; i ++)
    {
        for(int j = i + 1; j <= r; j ++)
        {
            if(a[j] < a[i]) swap(a[j], a[i]);
        }
    }
}

int main()
{
    int n, l, r;
    cin >> n >> l >> r;
    int a[n];
    for(int i = 0; i < n; i ++) cin >> a[i];
    
    sort(a, l, r);
    for(auto c: a) cout << c << " ";
    return 0;                                              
}
2.18 跳台阶

一个楼梯共有 n 级台阶,每次可以走一级或者两级,问从第 0 级台阶走到第 n 级台阶一共有多少种方案。

输入格式
共一行,包含一个整数 n。

输出格式
共一行,包含一个整数,表示方案数。

数据范围
1≤n≤15
输入样例:
5
输出样例:
8

//按递归函数写
#include 
using namespace std;

int func(int n)
{
    if(n == 1 || n == 0) return 1;
    else return (func(n - 1) + func(n - 2));    
}

int main()
{
    int n;
    cin >> n;
    cout << func(n) << endl;
    return 0;
}

//按递归搜索树的搜索顺序写
#include 
using namespace std;

int n;
int ans;
void f(int k)
{
    if(k == n) ans ++; 
    else if(k < n)
    {
        f(k + 1);
        f(k + 2);
    }
}

int main()
{
    cin >> n;
    f(0);
    cout << ans << endl;
    
    return 0;
}

递归函数的做法高度数学抽象化总结出规律(斐波那契),递归搜索树像是模拟了一遍所有的 2.19 走方格

给定一个 n×m 的方格阵,沿着方格的边线走,从左上角 (0,0) 开始,每次只能往右或者往下走一个单位距离,问走到右下角 (n,m) 一共有多少种不同的走法。

输入格式
共一行,包含两个整数 n 和 m。

输出格式
共一行,包含一个整数,表示走法数量。

数据范围
1≤n,m≤10
输入样例:
2 3
输出样例:
10

#include 
using namespace std;

int n, m;
int ans = 0;
void f(int x, int y)
{
    if(x == n && y == m ) ans ++;
    else if(x == n && y != m) f(x, y + 1);
    else if(x != n && y == m) f(x + 1, y);
    else
    {
        f(x + 1, y);
        f(x, y + 1);
    }
}
int main()
{
    cin >> n >> m;
    f(0, 0);
    cout << ans << endl;
    
    return 0;
}
2.20 排列

给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。

现在,请你按照字典序将所有的排列方法输出。

输入格式
共一行,包含一个整数 n。

输出格式
按字典序输出所有排列方案,每个方案占一行。

数据范围
1≤n≤9
输入样例:
3
输出样例:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

#include 
#include 
using namespace std;

const int N = 10;
int n;

void dfs(int k, int nums[], bool st[])
{
    if(k > n)
    {
    //1.为什么要从1开始,题目从1到9,数组填数的时候就不能填0,最小填1进去,所以数组是从1开始遍历的
    //2.遇到输出比较多的程序使用scanf和printf比较快
        for(int i = 1; i <= n; i ++) printf("%d ", nums[i]);
        puts("");
    }
    else 
    {
        for(int i = 1; i <= n; i ++)
        {
            if(!st[i])
            {
                st[i] = true;
                nums[k] = i;
                dfs(k + 1, nums, st);
                st[i] = false;//恢复现场
            }
        }
    }
    
}

int main()
{
    scanf("%d", &n);
    int nums[N];
    bool st[N] = {0};
    dfs(1, nums, st);
    
    return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/702208.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号