课后作业

2024/1/19

# 第十二课

# 1. 创建一个函数 max3,它接受三个整数参数并返回它们中的最大值。请在主函数中调用该函数,并打印出最大值

// 示例输入
3 5 7
// 示例输出:
最大值是 7
  • 历史解析

    • 变量初始化:在 main 函数中,只有 c 被初始化为0,而 ab 没有初始化。这不会影响程序的功能,因为这些变量随后通过 cin 赋值,如果你打算全部初始声明时便完成初始化可以如下定义
    int a = 0, b = 0, c = 0;
    
    • 变量命名:变量名 thet 在语义上不是很清晰。使用像 maxValue 这样更有描述性的变量名会更好
    • 代码简化max3 函数的逻辑可以被简化。目前的实现虽然正确,但包含了多个嵌套的 if 语句,这使得代码略显复杂
  • 参考答案

#include <iostream>
using namespace std;

int max3(int a, int b, int c) {
    int maxValue = a;
    if (b > maxValue) {
        maxValue = b;
    }
    if (c > maxValue) {
        maxValue = c;
    }
    return maxValue;
}

int main() {
    int a, b, c;
    cin >> a >> b >> c;
    cout << "最大值是: " << max3(a, b, c);
    return 0;
}

# 2. 该函数检查数字 x 是否在正整数 y 的某位中出现。如果出现则返回 xy 中的第一次出现的位置,否则返回 没有出现

// 示例输入
请输入 y: 2357
请输入 x: 3
// 示例输出:
x 位于 y 的第 2
  • 历史解析

    • 逻辑错误:在x_in_y函数中,for循环的条件 x % valu == 0 是错误的。这会导致循环在不正确的条件下终止。我们需要循环遍历数字y的每一位,直到y0,在判断tmp是否等于y时,代码写成了 if (tmp = y),这是赋值而不是比较。正确的比较操作是 if (tmp == y)。但实际上,我们应该比较tmpx
    • 算法问题:程序的目的是检查x是否是y的一部分,而不是检查它们是否相等。因此,我们需要在y中逐位检查。
  • 参考答案

#include <iostream>
using namespace std;

int x_in_y(int x, int y) {
    int pos = 0;
    while (y > 0) {
        pos++;
        if (y % 10 == x) {
            return pos;
        }
        y /= 10;
    }
    return -1;  // 表示没有出现
}

int main() {
    int x, y;
    cout << "请输入 y: ";
    cin >> y;
    cout << "请输入 x: ";
    cin >> x;
    int a = x_in_y(x, y);
    if (a != -1) {
        cout << "x 位于 y 的第 " << a << " 位";
    } else {
        cout << "没有出现";
    }
    return 0;
}

# 3. 编写一个函数 reverseInt,它接受一个整数参数并返回其数字反转后的结果。请在主函数中调用此函数并打印输出结果

// 示例输入
12345
// 示例输出
54321
  • 历史解析
    • 题解思路正确,使用了一个 for 循环,通过不断地取数字的个位并将其加入反转后的数字中,最终完成反转。这个算法是正确的,能够实现整数反转的功能,没有问题💯

# 4. 创建一个函数 countChar,它接受一个字符串和一个字符作为参数,返回该字符在字符串中出现的次数。请在主函数中调用此函数并打印输出结果

// 示例输入
请输入字符串: hello world
请输入字符: l
// 示例输出
字符 'l' 出现了 3
  • 历史解析

    • 函数原型不匹配要求: 函数 countChar 的原型应该是接收一个字符串和一个字符作为参数,返回该字符在字符串中出现的次数。但在提供的代码中,函数原型是 void countChar(int x, char* a, int &n),这不符合要求。 函数 countChar 中的参数 x 应该是 char 类型,而不是 int
    • 不必要的循环: 循环 for(int i=0; i<100; i++) 假设了字符串的最大长度为 100,这是不必要的。应当使用字符串的实际长度
    • 使用 gets 函数的风险gets 函数是不安全的,因为它可能导致缓冲区溢出。应该使用 fgetsscanf 之类的替代函数。
    • 声明错误:你不能认定字符串的长度最大为100
    • 调用错误:未调用countChar
  • 参考答案

#include <iostream>
#include <string>
using namespace std;

void countChar(const string& str, char x, int &count){
    int length = str.length(); // 获取字符串长度
    for(int i = 0; i < length; i++) {
        if(str[i] == x) {
            count++;
        }
    }
}

int main() {
    string str;
    char x;
    int count = 0;
    cout << "请输入字符串: ";
    // getline 是一个 C++ 标准库函数,用于从输入流中读取一行字符串
    // 它定义在 <string> 头文件中,通常与 istream 类型(如 cin)一起使用
    // getline 的常见用途是从标准输入读取一整行文本,直到遇到换行符(\n)
    getline(cin, str);
    cout << "请输入字符: ";
    cin >> x;
    countChar(str, x, count);
    cout << "字符 '" << x << "' 出现了 " << count << " 次" << endl;
    return 0;
}

# 5. 编写一个函数 isPrime,它接受一个整数参数并判断这个数是否为素数(只能被 1 和它本身整除的数)。如果是素数,返回 true;否则,返回 false。请在主函数中调用此函数并打印输出结果

// 示例输入
请输入一个整数: 29
// 示例输出
29 是素数
  • 历史解析

    • isPrime 函数中,如果 n 小于 2,则应该立即返回 false,因为 1 和负数不是素数
    • 检查到 sqrt(n)开平方)就足够了。因为如果 n 有一个大于 sqrt(n) 的因数,那么它必定还有一个小于等于 sqrt(n) 的因数。这可以减少循环的次数,提高效率
    • main 函数中,static_cast<bool> 是多余的,因为 isPrime(a) 的返回值本身就是布尔类型
  • 参考答案

#include <iostream>
#include <cmath>
using namespace std;

bool isPrime(int n) {
    if (n < 2) {
        return false;
    }
    for (int i = 2; i <= sqrt(n); i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

int main() {
    int a = 0;
    cout << "请输入一个整数: ";
    cin >> a;
    if (isPrime(a)) {
        cout << a << " 是素数" << endl;
    } else {
        cout << a << " 不是素数" << endl;
    }
    return 0;
}
上次更新: 2024-10-19 10:01:51