C++机试练习打卡

文章介绍了如何在C语言中实现查找列表元素的最大值、计算单链表中每个结点阶乘并求和,以及统计完全平方数和个位数字出现次数的函数。通过分解任务和优化算法,展示了基础编程技巧的应用。

5.实现一个函数可以求出列表中元素最大值

// 函数定义  
ElementType Max(ElementType S[], int N) {  
    // 假设数组至少有一个元素  
    ElementType max = S[0];  
    for (int i = 1; i < N; i++) {  
        // 如果当前元素大于max,则更新max  
        if (S[i] > max) {  
            max = S[i];  
        }  
    }  
    // 返回最大值  
    return max;  
}  

这种求最大值、最小值的不要直接本着去实现一个排序算法去,如上所示例的直接遍历整个列表,不断更新max值会更好。

6.对一个单链表的每个结点计算阶乘并求和

int FactorialSum( List L ){
    //遍历单链表
    int i;
    int temp;
    int sum;
    for(i=0;i<L.length;i++){
        //求每个结点的阶乘
        temp=mul(L[i])];
        //对阶乘结果求和
        sum+=temp;
        
    }

}
int mul(L[]){
    int mul=1;
    for(i=0;i<=L[];i++){
        mul*=i;
    }
    return mul;
}
#include <stdio.h>  
  
// 阶乘函数  
int factorial(int n) {  
    int result = 1;  
    for (int i = 1; i <= n; i++) {  
        result *= i;  
    }  
    return result;  
}  
  
// 计算链表结点阶乘和的函数  
int FactorialSum(List L) {  
    int sum = 0;  
    ListNode *current = L;  
      
    // 遍历链表  
    while (current != NULL) {  
        // 计算当前结点的阶乘并累加到sum中  
        sum += factorial(current->value);  
        // 移动到下一个结点  
        current = current->next;  
    }  
      
    // 返回阶乘和  
    return sum;  
}  
  

首先,将任务拆分成求阶乘和对求阶乘的结果求和,因此,用两个函数实现。上面的第一个代码块中思路基本正确,但是由于对链表数据结果掌握不够好,在定义方面存在错误。

主要有以下错误:

  1. 遍历单链表时由于不清楚单链表的长度,应当用while循环而不是for循环。
  2. 移动到下一个结点应该使用指针,而不是还像访问数组一样
  3. 初始化时,应当是初始化成链表名<ListNode> * 别名 <current>=L
  4. 阶乘函数的参数类型只需要和链表结点的data数据类型一致即可

此外,对链表的定义和别名以及应用有:

typedef struct Node *PtrToNode;
struct Node {
    int Data; /* 存储结点数据 */
    PtrToNode Next; /* 指向下一个结点的指针 */
};
typedef PtrToNode List; /* 定义单链表类型 */

说明:

这些定义在C语言中用于创建和操作单链表。下面我将逐一解释这些定义的含义和用法:

  1. typedef struct Node *PtrToNode;

这行代码定义了一个类型别名PtrToNode,它是指向struct Node的指针。通过使用typedef,我们可以使得指针的使用更为方便,避免了每次使用struct Node *时都要写完整的结构体指针声明。

  1. struct Node { ... };

这定义了一个名为Node的结构体,用于表示单链表中的一个节点。每个节点有两个成员:

  • int Data;:这是一个整型变量,用于存储节点中的数据。
  • PtrToNode Next;:这是一个指向下一个节点的指针。如果这是链表的最后一个节点,那么Next通常为NULL
  1. typedef PtrToNode List;

这行代码定义了另一个类型别名List,它实际上就是PtrToNode,即指向struct Node的指针。这个别名通常用于表示整个链表,因为链表的头节点(或称为起始节点)的指针可以用来遍历整个链表。

具体用法:

List CreateList() {  
    // 创建一个空链表  
    List head = NULL;  
    return head;  
}  
  
void InsertNode(List *head, int data) {  
    // 创建一个新节点  
    PtrToNode newNode = (PtrToNode)malloc(sizeof(struct Node));  
    if (newNode == NULL) {  
        printf("Memory allocation failed!\n");  
        exit(1);  
    }  
    newNode->Data = data;  
    newNode->Next = *head;  
    *head = newNode;  
}  
  
void PrintList(List head) {  
    PtrToNode current = head;  
    while (current != NULL) {  
        printf("%d ", current->Data);  
        current = current->Next;  
    }  
    printf("\n");  
}  

7. 统计某类完全平方数

本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144、676等。

int IsTheNumber ( const int N );

其中N是用户传入的参数。如果N满足条件,则该函数必须返回1,否则返回0。

#include <stdbool.h>  
#include <math.h>  
//将比较两位数是否相同转换为统计0-9数字出现的次数
bool hasDuplicateDigits(int num) {  
    int digitCounts[10] = {0}; // 用于记录0-9每个数字出现的次数  
    while (num > 0) {  
        int digit = num % 10;  
        digitCounts[digit]++;  
        if (digitCounts[digit] > 1) {  
            return true; // 如果某个数字出现超过一次,则返回true  
        }  
        num /= 10;  
    }  
    return false; // 所有数字都只出现一次,返回false  
}  
  
bool isPerfectSquare(int num) {  
    int root = (int)sqrt((double)num);  //sqrt用于计算平方根,这里先得到平方根再返回验证
    return (root * root == num); // 检查平方根的平方是否等于原数  
}  
  
int IsTheNumber(const int N) {  
    if (N < 10) { // 单位数无法满足至少有两位数字相同的条件  
        return 0;  
    }  
    if (isPerfectSquare(N) && hasDuplicateDigits(N)) {  
        return 1; // 如果满足完全平方和至少两位数字相同的条件,返回1  
    }  
    return 0; // 否则返回0  
}  

先分析问题将问题拆解后发现需要三个函数来实现,在这个例子中可以学到好多思维。

  1. 在c语言中要引入数学函数和bool类型需要include头文件<math.h>和<stdbool.h>
  2. 在设计函数逻辑时可以返回再验证如:bool isPerfectSquare(int num)
  3. 在比较两个数是否相同时,可以转化为统计每个数出现次数。

8. 简单阶乘计算

本题要求实现一个计算非负整数阶乘的简单函数。

int Factorial( const int N );

其中N是用户传入的参数,其值不超过12。如果N是非负整数,则该函数必须返回N的阶乘,否则返回0。

int Factorial(const int N) {  
    if (N < 0) {  
        // 如果N是负数,则返回0  
        return 0;  
    } else if (N == 0 || N == 1) {  
        // 0的阶乘和1的阶乘都是1  
        return 1;  
    } else {  
        int result = 1;  
        for (int i = 2; i <= N; ++i) {  
            result *= i;  
        }  
        return result;  
    }  
}  

这个题目重点考察if...else if...else...语句,此外还应分清楚测试示例的几种情况

9. 统计个位数字

本题要求实现一个函数,可统计任一整数中某个位数出现的次数。例如-21252中,2出现了3次,则该函数应该返回3。

int Count_Digit ( const int N, const int D );

其中ND都是用户传入的参数。N的值不超过int的范围;D是[0, 9]区间内的个位数。函数须返回ND出现的次数。

# include<stdlib.h>
// 函数用于统计整数N中数字D出现的次数  
int Count_Digit(const int N, const int D) {  
    int count = 0; // 用于计数D出现的次数  
    int temp = abs(N); // 取N的绝对值,以便处理负数  
  
    // 遍历整数N的每一位  
    if(N==0){
        return 1;
    }
    while (temp > 0) {  
        int digit = temp % 10; // 获取当前位的数字  
        if (digit == D) {  
            count++; // 如果当前位的数字是D,则增加计数  
        }  
        temp /= 10; // 去掉当前位,继续检查下一位  
    }  
  
    return count;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丹尼斯维奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值