0
点赞
收藏
分享

微信扫一扫

C++算法与数据结构_4

舟海君 2022-04-13 阅读 129

for 语句

for循环

  • for 循环语法:
for (循环变量赋初始值;循环条件;更新循环变量) {
    循环体
}

语法解析

  • 循环变量:用于控制循环的变量,一般在循环条件中使用
    • 比如:循环变量可以是在存钱100天这个例子中的天数
  • for循环的执行逻辑:
    • 首先会给循环变量赋一个初始值
    • 然后判断是否满足循环条件
      • 如果不满足,直接跳出循环;
      • 如果满足,执行循环体,更新循环变量,再跳回去重新判断是否满足循环条件。
        • 比如:输出存款总数,天数加1,再跳回去看看现在是不是依然满足循环条件
  • 使用for循环时,【循环变量赋初始值】,【循环条件】,【更新循环变量】这三个表达式都可以省略,变为for ( ; ; ) ,这表示不用给循环变量赋初始值,也不用在每次执行后更新循环变量,同时循环的条件始终为真,也就是说每次都会选择进入循环体。
  • 如果循环体只有一句话,可以不用大括号括起来
  • 举例

存钱100天的程序段:

// 输入一个整型变量表示存款总数量
int savings = 0;

// 用循环变量 i 表示现在的天数
// 最开始为1
// 每次循环后都加1天
// 不满足小于等于100天时就跳出循环
for (int i=1; i<=100; i++) {
    // 更新存款总数
    savings = savings + i;
    // 输出存款总数
    cout << i << ":总数" << savings << endl;
}

循环控制语句 break

  • 除了正常的循环之外,循环控制语句可以更改程序执行的正常序列。循环控制语句常用的是 breakcontinue
  • break 用法
    • switch语句中也有用到过,用于停止执行模块内后面的程序语句
    • 通常放在循环体中,当执行到这句语句时,跳出整个循环,也就是说整个循环立即终止
  • 举例:

存钱100天的例子,假设迷你键希望当存款总数到1000元时,就不存了,那他可以用break来终止循环

int savings = 0;

for (int i=1; i<=100; i++) {
    savings = savings + i;
    cout << i << ":总数" << savings << endl;
    
    // 当存到1000元时,跳出循环
    if (savings >= 1000)
        break;
}

循环控制语句 continue

  • 另一个常用的循环控制语句是 continue
  • continue 用法
    • 通常也是放在循环体中,当执行到这句语句时,跳过当前循环体,强迫进入下一次循环
  • 举例:

存钱100天的例子,假设如果天数是10的倍数(第10、20、30、…天),那么那天可以不存钱,也不输出存款总量。他可以用continue来跳过这几次循环

int savings = 0;

for (int i=1; i<=100; i++) {
    // 如果天数是10的倍数,直接进入下一天
    if (i % 10 == 0)
        continue;

    savings = savings + i;
    cout << i << ":总数" << savings << endl;
}

练习

  1. 输出21世纪(2001年1月1日至2100年12月31日的这一段期间称为21世纪)中截止某个年份以来的所有闰年年份。

    注意:闰年的判别条件是该年年份能被4整除但不能被100整除,或者能被400整除。

    输入描述:

    输入在一行中给出21世纪的某个截止年份。

    输出描述:

    逐行输出满足条件的所有闰年年份,即每个年份占一行。输入若非21世纪的年份则输出"Invalid year!"。若不存在任何闰年,则输出“None”。

    #include <bits/stdc++.h>
    using namespace std; 
    
    int main() {
        // 请补全代码,实现题目功能
        int year, outYear;
        bool mark = false;
        cin >> year;
        if ((year < 2001)||(year > 2100)){
            cout << "Invalid year!" << endl;
        }
        else {
            for (outYear = 2001; outYear <= year;   outYear++) {
                if (!(outYear % 400) || (!(outYear %    4) && (outYear % 100))) {
                    cout << outYear << endl;
                    mark = true;
                }
            }
        if (!mark) {
            cout << "None" << endl;
        }
    
        }
        return 0;
    }
    
  2. 给定大于1的整数n,求[1,n]区间上的数字之和。

    输入描述:

    一行,一个整数n

    输出描述:

    一行,数字之和

    #include <bits/stdc++.h>
    using namespace std; 
    
    int main() {
        // 请补全代码,实现题目功能
        int i, n, sum;
        cin >> n;
        sum = 0;
        for (i = 1; i <= n; i++) {
            sum += i;
    
        }
        cout << sum << endl;
        return 0;
    }
    

while 语句

while 循环

  • while循环只关注循环终止的条件和循环体的内容本身。
  • while 语法:
while (循环成立条件) {
    循环体
}
  • while 循环执行逻辑:
    • 只要循环成立条件为真,就进入循环体
    • 重复这个步骤,直到循环成立条件为假
  • 举例(猜数字)
// 声明生成的随机数字和猜的数字这两个变量
int num, guess;

// 提供随机种子
srand((unsigned)time(NULL));
// 随机生成一个1-100的数字
num = rand() % 100 + 1;

// 输入猜测的数字
cin >> guess;

// 如果猜的数字和生成的数字不相同就进入循环
while (guess != num) {
    // 输出猜大了还是猜小了
    if (guess > num)
        cout << "猜大了" << endl;
    else if (guess < num)
        cout << "猜小了" << endl;
    
    // 重新输入猜测的数字
    cin >> guess;
}

// 当猜的数字和生成的数字相同时,跳出循环后,输出“猜对了”
cout << "猜对了" << endl;

do while 循环

  • 无论如何,至少要执行一次猜数字的操作,可以用 do while 的写法

Tips:在刚刚的代码中,可以发现在循环体里有猜数字(cin >> guess)的操作,在循环开始前也有猜数字的操作。这就适合用 do while

  • do while 语法
do {
    循环体
} while (循环成立条件);
  • do while 执行逻辑
    • while类似
    • 唯一的区别在于:因为条件表达式出现在循环的尾部,所以至少会执行一次循环体,执行完成后,再判断是否进入下一次循环。

举例

do while来写猜数字游戏的程序段:

// 声明生成的随机数字和猜的数字这两个变量
int num, guess;

// 提供随机种子
srand((unsigned)time(NULL));
// 随机生成一个1-100的数字
num = rand() % 100 + 1;

do {
    // 输入猜测的数字
    cin >> guess;
    
    // 输出猜大了还是猜小了
    if (guess > num)
        cout << "猜大了" << endl;
    else if (guess < num)
        cout << "猜小了" << endl;
} while (guess != num);

// 当猜的数字和生成的数字相同时,跳出循环后,输出“猜对了”
cout << "猜对了" << endl;

练习

  1. 输入一个小于10000的整数,判断其是否为质数,若是则输出yes,否则输出no(请用while语法实现)

    输入描述:

    一行,一个正整数

    输出描述:

    一个字符串,yes或no

    #include <bits/stdc++.h>
    using namespace std; 
    
    int main() {
        // 请补全代码,实现题目功能
        int num, i = 2;
        bool mark = false;
        cin >> num;
        if (num == 2) {
            cout << "yes" << endl;
        }
        else {
            while (i < num) {
                if (num % i) {
                    i++;
                    mark = true;
                }
                else {
                    mark = false;
                    break;
                }
            }
            if (mark) 
                cout << "yes" << endl;
            else 
                cout << "no" << endl;
        }
    
        return 0;
    }
    

多重循环

正如if语句可以通过嵌套,实现分支内部的新分支,循环也是可以嵌套的。

  • 循环嵌套适用于循环的大操作里有重复的小操作的情景。
  • 举例:打印一个九九乘法表:

循环的大操作:对于1-9,每个数字都打印一行  大操作中重复的小操作:在第i行里,对于每个小于等于i的数字j,都打印出i和j组成的乘法公式。

如果我们用for循环内部嵌套for循环的方式来写,代码是这样实现的:

// 1-9,每个数字打印一行
for (int i = 1; i <= 9; i++) {
    // 在第i行中,对于每个小于i的数字,都打印一个等式和tab分隔
    for (int j = 1; j <= i ; j++) {
        cout << j << "*" << i << "=" << j*i << "\t";
    }
    // 第i行最后打印换行符
    cout << endl;
}

如果我们用for循环内部嵌套while循环的方式来写,代码就是这样的:

// 1-9,每个数字打印一行
for (int i = 1; i <= 9; i++) {
    // 在第i行中,对于每个小于i的数字,都打印一个等式和tab分隔
    int j = 1;
    while (j <= i) {
        cout << j << "*" << i << "=" << j*i << "\t";
        j++;
    }
    // 第i行最后打印换行符
    cout << endl;
}

通过这个例子,我们一起来看看循环嵌套的注意事项:

  • 可以任意嵌套,比如forforforwhilewhileforwhilewhile都可以
  • 如果是forfor,内外层的循环变量(比如上述代码的i和j)需要用不一样的变量,否则容易产生混乱
  • 在嵌套操作中都需要使用缩进,以增强代码可读性
  • 可以多层嵌套,但是有时候太多层嵌套容易超时,需要引起注意

练习

  1. 打印出n层高的*三角形

    输入描述:

    一行,一个整数n

    输出描述:

    从上向下数,第i层有i个星号,左对齐

    #include <bits/stdc++.h>
    using namespace std; 
    
    int main() {
        // 请补全代码,实现题目功能
        int i, j, n;
        cin >> n;
        for (i = 1; i <= n; i++) {
            for (j = 1; j <= i; j++) {
                cout << '*';
            }
            cout << endl;
        }
        return 0;
    }
    
  2. 小明钱包里装着各种纸币。纸币有4种(纸币的类型有1元、3元、5元和10元),每一种分别有a、b、c、d张。现在小明要出门买东西,他需要支付N元,在不找零的情况下,请问能支付成功吗?如果能成功支付,那么请计算出有多少种支付方式;如果不能成功支付,就输出no。

    输入描述:

    输入共 1 行,包含 5个整数 a、b、c、d、n,之间用一个空格隔开。abcd小于11

    输出描述:

    如果不能成功支付,则输出:no

    如果可以成功支付,则输出:一个整数,表示支付方式的总数

    #include <iostream>
    using namespace std;
    
    int main() {
        // 1,3,5,10的张数,以及总价,枚举时的支付价,支付   方式数量
        int a, b, c, d, n, sum, num=0;
        cin >> a >> b >> c >> d >> n;
    
        for (int i=0; i<=d; i++) {
            if (i*10 > n)
                break;
            for (int j=0; j<=c; j++) {
                if ((i*10 + j*5) > n)
                    break;
                for (int k=0; k<=b; k++) {
                    if ((i*10 + j*5 + k*3) > n)
                        break;
                    for (int p=0; p<=a; p++) {
                        sum = i*10 + j*5 + k*3 + p;
                        if (sum == n)
                            num += 1;
                        else if (sum > n)
                            break;
                    }
                }
            }
        }
    
        if (num)
            cout << num << endl;
        else
            cout << "no" << endl;
    
        return 0;
    }
    
    • A重数的循环
      当一个n位数k的每一位都是同样的数字a时,我们把k称作a的n重数,例如666被称为6的三重数。

    现在给定t(1≤ t ≤ 20)对a和n,求a的n重数k。

    对于100%的数据满足1 ≤ k ≤ 10^11。

    输入描述:

    第一行一个整数t,

    接下来t行,每行两个整数 a,n,中间1个空格间隔

    输出描述:

    输出共t行,每行一个整数 k

    示例 1:

    输入:
    2
    1 2
    6 3
    输出:
    11
    666
    

    代码:

    #include <iostream>
    using namespace std;
    
    int main() {
        int t, a, n;
      	long long num;
        cin >> t;
        for (int i = 0; i < t; i++) {
            cin >> a >> n;
            num = a;
            for (int j=2; j<=n; j++)
                num = num * 10 + a;
            cout << num << endl;
        }
        
        return 0;
    }
    
举报

相关推荐

0 条评论