红皮书C语言(六章)

差不多就这些,不会再更新。
第六章------数组二

1,C语言实现,编写函数,对n个字符按字典顺序排序,限定函数名为void sort(char st[][10],int n)

思路:使用strcmp函数与strcpy函数

#include <stdio.h>
#include <string.h>
void sort(char st[][10], int n) {
    char temp[10];
    int i, j;
    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            if (strcmp(st[i], st[j]) > 0) {
                strcpy(temp, st[i]);
                strcpy(st[i], st[j]);
                strcpy(st[j], temp);
            }
        }
    }
}
int main() {
    char st[][10] = {"hello", "world", "c", "language", "prog"};
    int n = 5;
    sort(st, n);
    int i;
    for (i = 0; i < n; i++) {
        printf("%s ", st[i]);
    }
    printf("\n");
    return 0;
}

2.设有n的非负整数存放于一维数组中,要求将其中的0移到后面,非0数保持原有次序,例如,当n=7时,7003050移动为7350000

思路:找出非0的数存在另一数组,其他元素置0再输出

#include <stdio.h>
void moveZeros(int arr[], int n)
{
    int ZeroIndex = 0;
    for (int i = 0; i < n; i++) {
        if (arr[i] != 0) {
            arr[ZeroIndex] = arr[i];
            ZeroIndex++;
        }
    }
    for (int i = ZeroIndex; i < n; i++) {
        arr[i] = 0;
    }
}
int main()
{
    int arr[] = {7, 0, 0, 3, 0, 5, 0};
    int n = sizeof(arr) / sizeof(arr[0]);//求长度
    moveZeros(arr, n);
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

3.编写一个函数,给定A中删除元素值在x和y(x<=y)之间的所有元素,(向量要求中间不能有间隔),函数原型为int del (int A,int n,int x,int y)

注:此题与数据结构线性表课后第4-5习题类似

思路:便利数组看是否在区间范围内,通过k统计删除个数,k是下一个元素要前移的位置

#include <stdio.h>
int del(int A[], int n, int x, int y) {
    int i, k=0;
    for (i = 0; i < n; i++){
        if (A[i] >= x && A[i] <= y) {
            k++;
        }else
        A[i-k] = A[i];
    }
    return n-k;
}
int main() {
    int A[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int n = 10;
    int x = 3, y = 7;
    n = del(A, n, x, y);
    for (int i = 0; i < n; i++) {
        printf("%d ", A[i]);
    }
    return 0;
}

4,编写函数把整数数组中相同的元素删除的只剩一个,并把剩余元素移到前面

注:与线性表课后题2-3类似,具体位置记不清

思路:

#include <stdio.h>
void remove_same(int arr[], int size) {
    int i, j, k;
    for (i = 0; i < size; i++) {
        for (j = i + 1; j < size;) {
            if (arr[j] == arr[i]) {
                for (k = j; k < size; k++) {
                    arr[k] = arr[k + 1];
                }
                size--;
            } else {
                j++;
            }
        }
    }
    for (i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
int main() {
    int arr[] = {1,2,2,2,3,3,3,4,4,5};
    int size = sizeof(arr) / sizeof(arr[0]);
    remove_same(arr, size);
    return 0;
}

5.二维数组A(10*10)每行最大元素构成向量B,每列最小元素构成向量C,求B*C

思路:用具体数值比较直观,遍历找到每行最大元素存入A,同理B

#include <stdio.h>
int main() {
    int A[10][10] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
                     {11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
                     {21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
                     {31, 32, 33, 34, 35, 36, 37, 38, 39, 40},
                     {41, 42, 43, 44, 45, 46, 47, 48, 49, 50},
                     {51, 52, 53, 54, 55, 56, 57, 58, 59, 60},
                     {61, 62, 63, 64, 65, 66, 67, 68, 69, 70},
                     {71, 72, 73, 74, 75, 76, 77, 78, 79, 80},
                     {81, 82, 83, 84, 85, 86, 87, 88, 89, 90},
                     {91, 92, 93, 94, 95, 96, 97, 98, 99, 100}};
    int i, j, max, min;
    int B[10], C[10];
    // 计算B向量
    for (i = 0; i < 10; i++) {
        max = A[i][0];
        for (j = 1; j < 10; j++) {
            if (A[i][j] > max) {
                max = A[i][j];
            }
        }
        B[i] = max;
    }

    // 计算C向量
    for (j = 0; j < 10; j++) {
        min = A[0][j];
        for (i = 1; i < 10; i++) {
            if (A[i][j] < min) {
                min = A[i][j];
            }
        }
        C[j] = min;
    }
    // 计算B*C
    int result = 0;
    for (i = 0; i < 10; i++) {
        result += B[i] * C[i];
    }
    printf("B*C = %d\n", result);
    return 0;
}

6.编写函数,判断给定的整数数组a[n]中是否存在a[i](0<i<n),等于其前边所有元素之和,即a[i]=a[1]+a[2]+……a[i-1].

#include <stdio.h>
int isExist(int a[], int n) {
    int sum = 0;
    for(int i = 1; i < n; i++) {
        sum += a[i-1];
        if(sum == a[i]) {
            return 1;
        }
    }
    return 0;
}
int main() {
    int a1[] = {1, 2, 3,6};
    if(isExist(a1, 4)) {
        printf("a1中存在满足条件的元素\n");
    } else {
        printf("a1中不存在满足条件的元素\n");
    }
    return 0;
}

7,编写函数int delarr(int a[ ],int n),删除n个元素的正整数数组a中所有素数,要求,数组中剩余元素保持原有次序,并将处理后的数组输出,函数返回剩余元素个数,不能定义额外的新数组。

#include <stdio.h>
int isPrime(int num) { // 判断素数
    if (num <= 1) return 0;
    for (int i = 2; i*i <= num; i++) {
        if (num % i == 0) return 0;
    }
    return 1;
}
int delarr(int a[], int n) {
    int count = 0; // 剩余元素个数
    for (int i = 0; i < n; i++) {
        if (!isPrime(a[i])) { // 如果当前元素不是素数
            a[count++] = a[i]; // 将该元素添加到剩余元素中
        }
    }
    printf("处理后的数组:");
    for (int i = 0; i < count; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return count;
}
int main() {
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 测试数组
    int n = 10;
    int remain = delarr(a, n);
    printf("剩余元素个数:%d\n", remain);
    return 0;
}

8.编写函数,对一个给定的字符串中所有字符(不考虑默认字符串结束字符'\0'),进行排序,使得排序后的字符串满足从左到右为ASCII码递增的字符序列。

#include <stdio.h>
#include <string.h>
void sort_string(char* str) {
    int len = strlen(str);
    int i, j, temp;
    for (i = 0; i < len-1; i++) {
        for (j = i+1; j < len; j++) {
            if (str[i] > str[j]) {
                temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
        }
    }
}
int main() {
    char str[100];
    printf("Enter a string: ");
    scanf("%s", str);
    sort_string(str);
    printf("Sorted string: %s\n", str);
    return 0;
}

9,编写函数 int mergearr(int a[ ],int m,int b[ ],int n),将两个严格增序数组a和b合并后存储在a中,并保证处理后的数组依然严格有增序,函数值返回合并后数组a中元素个数,不能定义额外的新数组。

#include<stdio.h>
#include<stdlib.h>
int mergearr(int a[], int m, int b[], int n) {
    int i = m - 1;
    int j = n - 1;
    int k = m + n - 1;
    while (i >= 0 && j >= 0) {
        if (a[i] > b[j]) {
            a[k--] = a[i--];
        } else {
            a[k--] = b[j--];
        }
    }
    while (j >= 0) {
        a[k--] = b[j--];
    }
    return m + n;
}
int main(){
    int a[7] = {1, 3, 5, 7, 9, 11, 13};
    int b[5]={2,4,6,8,10};
    int m = mergearr(a, 7, b, 5);
    for (int i = 0; i < m;i++){
        printf("%d ", a[i]);
    }
}

10,使用数组精准计算M/N,(0<N<M<=100)的各小数位的值,如果M/N是无限循环小数,则计算并输出它的第一循环节,同时输出循环节的起止位置(小数的序号)。

思路:程序先读入两个正整数m和n,然后采用长除法的方法计算M/N,同时记录下每一步的商(整数部分)和余数的值。如果余数为0,说明计算过程已经结束,程序也将停止计算。如果在计算过程中发现两个商的值相同,就说明出现了循环节,程序将记录下循环节的起止位置。

最后程序将输出计算结果和循环节的起止位置。需要注意的是,如果M/N是整数,输出结果时还需要在整数部分后面加上一个小数点。

#include <stdio.h>
int main()
{
    int m, n;
    printf("请输入两个正整数m和n,其中0 < n < m <= 100:");
    scanf("%d%d", &m, &n);
    int a[110] = {0}; // 用于记录除法的每一步操作
    int start = -1, end = -1; // 循环节的起止位置
    int q = m / n; // 整数部分
    int r = m % n; // 第一步余数
    a[0] = q;
    int i = 1;
    while (r != 0 && i <= 100) {
        q = r * 10 / n;
        r = r * 10 % n;
        for (int j = 0; j < i; j++) {
            if (a[j] == q) {
                start = j;
                end = i - 1;
                break;
            }
        }
        if (start != -1) {
            break;
        }
        a[i++] = q;
    }
    printf("结果为:");
    for (int j = 0; j < i; j++) {
        printf("%d", a[j]);
        if (j == 0) {
            printf(".");
        } else if (j == start + 1) {
            printf("(");
        }
    }
    if (start != -1) {
        printf(")");
    }
    printf("\n循环节起止位置为:%d ~ %d\n", start, end);
    return 0;
}

11,已知线性表A长为n,采用顺序存储结构,写一个算法,删除该表中所有值为item的数据元素。

#include<stdio.h>
void deleteItem(int A[], int n, int item) {
    // 遍历表,寻找要删除的元素
    int i, j;
    for (i = 0, j = 0; i < n; i++) {
        if (A[i] != item) {// 非删除元素,保留到前面
            A[j++] = A[i];// 剩余元素移到末尾,并更新长度
        }
    }
    n = j;
    printf("删除元素%d后,长度为%d,结果为:", item, n);
    for (i = 0; i < n; i++) {
        printf("%d ", A[i]);
    }
}
int main(){
    int a[] = {1, 2, 2, 2, 3, 3, 3, 5, 5};
    int item = 3;
    int n = 9;
    deleteItem(a, n, 5);
}

12,求一个3*3的整型矩阵对角线之和

#include <stdio.h>
int main() {
    int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; // 定义一个3x3的整型矩阵并初始化
    int i, j, sum = 0;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            if (i == j) { // 判断是否在对角线上
                sum += matrix[i][j];
            }
        }
    }  
    printf("对角线之和为:%d", sum);
    return 0;
}

或者函数实现

#include<stdio.h>
int dsum(int a[][3],int n){//传参
    int i, sum = 0;
    for (i = 0; i < n;i++)
        sum += a[i][i];
    return sum;
}
int main(){
    int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int sum = dsum(a, 3);
    printf("对角线之和为:%d", sum);
    return 0;
}

13,编写程序输出10*10的螺旋矩阵(代码转自)

#include<stdio.h>
int main() {
    int n = 10;
    int matrix[n][n];
    int num = 1;
    int i, j, k, l;
    // 初始化矩阵
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            matrix[i][j] = 0;
        }
    }
    // 填充螺旋矩阵
    for (i = 0, j = 0, k = n - 1, l = n - 1; num <= n * n;) {
        for (int x = j; x <= l && num <= n * n; x++) {
            matrix[i][x] = num;
            num++;
        }
        i++;
        for (int x = i; x <= k && num <= n * n; x++) {
            matrix[x][l] = num;
            num++;
        }
        l--;
        for (int x = l; x >= j && num <= n * n; x--) {
            matrix[k][x] = num;
            num++;
        }
        k--;
        for (int x = k; x >= i && num <= n * n; x--) {
            matrix[x][j] = num;
            num++;
        }
        j++;
    }
    // 输出螺旋矩阵
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            printf("%4d", matrix[i][j]);
        }
        printf("\n");
    }
    return 0;
}

14,排序问题,给定10*10矩阵a,编写程序对a进行排序,要求a[i1][j1]<=a[i1][j2],若j1<j2,a[i1][j1]<=a[i2][j2],若i1<i2

//代码有bug,多输出8,没改好
#include<stdio.h>
void sort(int a[][10]){
    int i, j, temp, *p;
    p = &a[0][0];
    for (i = 0; i < 100;i++){
        for (j = 0; j < 100 -i;j++){
            if(*(p+j)>*(p+j+1)){
                temp = *(p + j);
                *(p + j) = *(p + j + 1);
                *(p + j + 1) = temp;
            }
        }
    }
}
int main(){
    int a[10][10]={
        {10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
        {20, 19, 18, 17, 16, 15, 14, 13, 12, 11},
        {30, 29, 28, 27, 26, 25, 24, 23, 22, 21},
        {40, 39, 38, 37, 36, 35, 34, 33, 32, 31},
        {50, 49, 48, 47, 46, 45, 44, 43, 42, 41},
        {60, 59, 58, 57, 56, 55, 54, 53, 52, 51},
        {70, 69, 68, 67, 66, 65, 64, 63, 62, 61},
        {80, 79, 78, 77, 76, 75, 74, 73, 72, 71},
        {90, 89, 88, 87, 86, 85, 84, 83, 82, 81},
        {100, 99, 98, 97, 96, 95, 94, 93, 92, 91}
    };
    sort(a);
    for (int i = 0; i < 10;i++){
        for (int j = 0; j < 10;j++){
            printf("%d  ", a[i][j]);
        }
        printf("\n");
    }
}
第七章------平台频率问题

1,设给定n个元素的一维整型数组变量A,若有下面条件,A[i-1]!=A[i],A[i]=A[i+1]=……A[k],A[k]!=A[k+1],则称A[i],A[i+1]……A[k],为饱和平台,并定义长度为k+1-i;试写函数,使得它对任给的数组变量A求出平台的长度

例如:有序列(3,3,2,2,4,4,4),则(3,3)和(2,2)及(4,4,4)都是饱和平台,并且最长的平台长度为3

#include <stdio.h>
int findPlatformLength(int A[], int n) {
    int max_len = 0;
    int i = 0;
    while (i < n) {
        int j = i + 1;
        while (j < n && A[j] == A[i]) {
            j++;
        }
        int len = j - i;
        if (len > 1 && max_len < len) {
            max_len = len;
        }
        i = j;
    }
    return max_len;
}
int main() {
    int A[] = {3,3,7,7,7,7,5,2,2,2,2,4,4,4};
    int n = sizeof(A) / sizeof(A[0]);
    int len = findPlatformLength(A, n);
    printf("The maximum length of platform is %d\n", len);
    return 0;
}

2,设有一递减整数序列,把所有相同的数组合成的子序列成为平台,自称平台的数的个数称为平台长度,编写函数,求长度为n的序列中最长的平台长度。

#include <stdio.h>
int longestPlatform(int arr[], int n) {
    int maxLen = 1, len = 1; // 初始化最大平台长度和当前平台长度
    for (int i = 1; i < n; i++) {
        if (arr[i] == arr[i - 1]) { // 如果当前元素与前一个元素相同,说明该元素在平台上
            len++; // 当前平台长度加1
        } else { // 如果当前元素与前一个元素不同,说明平台已结束
            if (len > maxLen) { // 如果当前平台长度比最大平台长度还要长,更新最大平台长度
                maxLen = len;
            }
            len = 1; // 重置当前平台长度为1
        }
    }
    if (len > maxLen) { // 处理最后一个平台
        maxLen = len;
    }
    return maxLen;
}
int main() {
    int arr[] = {9, 8, 8, 8, 8, 7, 3, 3, 1, 1, 1};
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("最长平台长度为%d\n", longestPlatform(arr, n)); // 输出最长平台长度
    return 0;
}

3,给S=00010111001110001111,返回N1=4,N0=3

#include <stdio.h>
#include <string.h>
int main(){
    char s[] = "1001111000111110";
    int n1 = 0, n0 = 0, len = strlen(s);
    int count1 = 0, count0 = 0;
    for (int i = 0; i < len; i++){
        if (s[i] == '1'){
            count1++;
            count0 = 0;
            if (count1 > n1){
                n1 = count1;
            }
        }
        else{
            count0++;
            count1 = 0;
            if (count0 > n0){
                n0 = count0;
            }
        }
    }
    printf("N1=%d, N0=%d", n1, n0);
    return 0;
}

4,设A是5*5的二维数组,编一函数,求A中出现频率最高的数

#include <stdio.h>
int findFreq(int A[][5], int n) {
    int freq[26] = {0}; // 用一个一维数组freq来记录每个数字出现的次数,freq[1]表示数字1出现的次数,以此类推
    int maxFreq = 0;   // 存储出现次数最多的数字的出现次数
    int mostFreq = 0;  // 存储出现次数最多的数字
    // 遍历二维数组,统计各个数字出现的次数
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            int num = A[i][j];
            freq[num]++;
            if (freq[num] > maxFreq) {
                maxFreq = freq[num];
                mostFreq = num;
            }
        }
    }
    return mostFreq;
}
int main() {
    int A[5][5] = {
        {3,2,4,5,1},
        {10,9,3,4,2},
        {8,7,6,7,7},
        {3,3,4,1,2},
        {4,5,3,1,1}
    };
    int mostFreq = findFreq(A, 5);
    printf("出现频率最高的数是:%d\n", mostFreq);
    return 0;
}

5,输入一行字符,分别统计出其中英文字母,空格,数字和其他字符的个数。

#include <stdio.h>
int main()
{
    char ch;
    int letter = 0, space = 0, digit = 0, other = 0;
    printf("请输入一行字符:\n");
    while ((ch = getchar()) != '\n')
    {
        if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z')
            letter++;
        else if (ch == ' ')
            space++;
        else if (ch >= '0' && ch <= '9')
            digit++;
        else
            other++;
    }  
    printf("其中英文字母有%d个,空格有%d个,数字有%d个,其他字符有%d个。\n", letter, space, digit, other);
    return 0;
}

6,编写函数,对给定的有序整数数组进行整理,使得所有整数重复二次出现。

例如原数组为-2,-1,-1,0,0,1,4,4,4,则处理后的结果为:-2,-2,-1,-1,-1,-1,0,0,0,0,4,4,4,4,4,4

//有bug,脏数据没改过来
#include <stdio.h>
void f(int a[],int n){
    int i, j;
    for (i = 0; i < 2 * n;i+=2){
        for (j = n + i; j > i;j--)
            a[j] = a[j - 1];
    }
}
int main() {
    int arr[] = {-2,-1,-1,0,0,1,4,4,4};
    int len = sizeof(arr) / sizeof(arr[0]);
    f(arr, len);
    for (int i = 0; i < 2*len;i++)
        printf("%d ", arr[i]);
        return 0;
}

7,已知一维数组A中存放了200个整数,编写代码段,功能是输出该数组中所有不同的数据值以及在该数组中出现的次数,即:对数组中数值不同的数据各自出现的频率进行统计.

eg:数组有十个元素,3,5,3,3,10,7,7,5,3,7

该程序能够输出:3出现的次数是4,5出现的次数是2,10出现的次数是1,7出现的次数是3

#include <stdio.h>
int main() {
    int A[10], frequency[10] = {0}; // frequency数组用于记录每个数值出现的频率
    int size = 10;
    printf("请输入200个整数:\n");
    for (int i = 0; i < size; i++) {
        scanf("%d", &A[i]);
    }
    for (int i = 0; i < size; i++) {
        int flag = 0; // 用于判断该数值是否已经被统计过
        for (int j = 0; j < i; j++) {
            if (A[i] == A[j]) {
                flag = 1;
                break;
            }
        }
        if (!flag) {
            int count = 1;
            for (int j = i + 1; j < size; j++) {
                if (A[i] == A[j]) {
                    count++;
                }
            }
            printf("%d出现的次数是%d\n", A[i], count);
        }
    }
    return 0;
}

8,设有字符串S以及长度为n的字符型一维数组a,编写一个函数统计a中每个字符在S中出现的次数,要求该函数以s,a,n为形参,一维整型数组为返回值。

#include <stdio.h>
int* count_chars(char* s, char* a, int n) {
    static int counts[26]; // 存储26个字母出现次数的数组
    int i, index;
    for (i = 0; i < n; i++) {
        index = a[i] - 'a'; // 计算出当前字符在字母表中的位置
        if (index >= 0 && index < 26) { // 如果当前字符是小写字母
            counts[index]++; // 将当前字符的出现次数加1
        } else {
            printf("Error: %c is not a lowercase letter!\n", a[i]); // 如果当前字符不是小写字母,输出错误信息
        }
    }
    return counts; // 返回存储字母出现次数的数组
}
int main() {
    char s[] = "hello world";
    char a[] = "abcdeefghijklmnopqrstuvwxyz"; // 只有字母表中的字符会被统计
    int n = sizeof(a) / sizeof(char);
    int* counts = count_chars(s, a, n);
    int i;
    for (i = 0; i < 26; i++) {
        printf("%c: %d\n", 'a' + i, counts[i]);
    }
    return 0;
}

9,编写一个程序,统计输入的字符串中每一个小写字母出现的次数。

#include <stdio.h>
#include <string.h>
int main() {
    char str[100];
    int count[26] = {0};
    int i, len;
    printf("请输入一个字符串:");
    scanf("%s", str);
    len = strlen(str);
    for (i = 0; i < len; i++) {
        if (str[i] >= 'a' && str[i] <= 'z') {
            count[str[i] - 'a']++; // 将字符转换成数组下标进行计数
        }
    }
    printf("每一个小写字母出现的次数:\n");
    for (i = 0; i < 26; i++) {
        if (count[i] > 0) {
            printf("%c: %d\n", i + 'a', count[i]); // 将数组下标转换成字符输出
        }
    }
    return 0;
}
第八章------找规律与泰勒

1,输出s的值,精度1e-6

S=(1/1)*(2/1)+(1/3)*(4/3)……

书上原代码------感觉不对,思路和代码对不上
#include <stdio.h>
int main() {
    int n;
    float term = 1, s = 0.0;
    for (n = 1; term > 1e-6;n+=1){
        term = 1.0 / (2 * n - 1) * 2.0 * n / (2 * n - 1);
        s += term;
    }
    printf("%f", s);
}
#include <stdio.h>
int main()
{
    double s = 0.0;
    double a = 1.0;
    int i = 1;
    while (a >= 1e-6) {
        s += a;
        i++;
        a *= (double)(i * i - 1) / (double)(i * i);
    }
    printf("S = %lf\n", s);
    return 0;
}

2,魔方阵,每一行每一列和对角线之和均相等,要输出1~n方的自然数构成的魔方阵。

思路:

使用一个循环来填充数字。填充数字的规则如下:

  1. 将第一个数放置在第一行中间。
  2. 每次往右上方填写一个数。
  3. 如果需要填写的位置已经有数了,就填在下面一个位置,取模运算保证下标在0~n-1的范围内。
#include <stdio.h>
void generate_magic_square(int n) {
    int magic_square[n][n]; // 定义n阶魔方阵
    int row, col, num;
    // 初始化所有格子都为0
    for (row = 0; row < n; row++) {
        for (col = 0; col < n; col++) {
            magic_square[row][col] = 0;
        }
    }
    // 将第一个数放置在第一行中间
    row = 0;
    col = n / 2;
    magic_square[row][col] = 1;
    // 循环填充数字
    for (num = 2; num <= n * n; num++) {
        // 判断需要填数字的位置是否已经被占用
        if (magic_square[(row - 1 + n) % n][(col + 1) % n] == 0) {
            // 如果位置没有被占用,将数字填入该位置
            row = (row - 1 + n) % n;
            col = (col + 1) % n;
        } else {
            // 如果位置已经被占用,将数字填在下面一个位置
            row = (row + 1) % n;
        }
        magic_square[row][col] = num;
    }
    // 输出魔方阵
    printf("Magic square of order %d:\n", n);
    for (row = 0; row < n; row++) {
        for (col = 0; col < n; col++) {
            printf("%d ", magic_square[row][col]);
        }
        printf("\n");
    }
}
int main() {
    int n;
    printf("Enter the order of magic square (odd number): ");
    scanf("%d", &n);
    generate_magic_square(n);
    return 0;
}

3,有一个分数序列,2/1,3/2,5/3,8/5,13/8,21/13,求这个数列前20项和

思路:代码中的 a 和 b 分别代表斐波那契数列中的前两项,temp 用来保存上一个分子的值。每次循环中,我们首先计算当前项的值并将其累加到 sum 变量中,然后更新 a 和 b 的值,以便计算下一项。

#include <stdio.h>
int main() {
    int n = 20; // 前20项
    int i;
    double a = 2, b = 1, temp, sum = 0;
    for (i = 1; i <= n; i++) {
        sum += a / b; // 累加当前项的值
        temp = a; // 保存上一个分子的值
        a = a + b; // 计算当前项的分子
        b = temp; // 将上一个分子作为当前项的分母
    }
    printf("前20项的和为: %.2f", sum);
    return 0;
}

4,编写程序,顺序生成前100项,序列的第一项,第二项分别为2,3,后继项按如下方法生成,1)若序列的最后两项的乘积是一位数,则此一位数即为后继项

2)若序列的最后两项乘积是两位数,则此两位数的十位数字和个位数字分别为后继的连续两项。

#include <stdio.h>
int main()
{
    int seq[100];  // 存储序列的数组
    seq[0] = 2;    // 第一项为2
    seq[1] = 3;    // 第二项为3
    for (int i = 2; i < 100; i++) {  // 生成前100项
        int product = seq[i-1] * seq[i-2];  // 计算前两项的乘积
        if (product < 10) {  // 乘积是一位数
            seq[i] = product;  // 直接作为后继项
        } else {  // 乘积是两位数
            int tens = product / 10;  // 十位数字
            int units = product % 10;  // 个位数字
            seq[i] = tens + units;  // 将十位和个位数字相加作为后继项
        }
    }
    // 输出前100项
    for (int i = 0; i < 100; i++) {
        printf("%d ", seq[i]);
    }
    printf("\n");
    return 0;
}

5,编写程序,输出序列前100项,该序列第一项为0,第二项为1,以后的奇数项为其前两项之和,偶数项为前两项之差。

#include <stdio.h>
int main() {
    int a = 0, b = 1, c = 0;
    printf("%2d%2d", a, b);
    for (int i = 3; i <= 100; i++) {
        if (i % 2 == 1) {
            c = a + b;
        } else {
            c = a - b;
        }
        printf("%2d", c);
        a = b;
        b = c;
    }
    return 0;
}

6,编写程序实现调和级数前N项和,要求结果是一个准确的分数A/B形式

#include <stdio.h>
int main() {
    int N, i;
    int A = 0, B = 1; // 初始化分数为0/1
    printf("请输入调和级数的项数N:");
    scanf("%d", &N);
    for (i = 1; i <= N; i++) {
        int a = B, b = i; // 本次加的分数为1/i
        A = A * b + a * B;
        B = B * b;
        // 化简分数
        int gcd = 1, j;
        for (j = 2; j <= A && j <= B; j++) {
            if (A % j == 0 && B % j == 0) {
                gcd = j;
            }
        }
        A /= gcd;
        B /= gcd;
    }
    printf("调和级数前%d项和为:%d/%d\n", N, A, B);
    return 0;
}

7,编写函数,实现按照如下公式计算的功能。

f(n)=2/(3*0!)+3/(4*1!)+4/(5*2!)+……n/((n+1)*(n-2)!),其中n为自然数,且n>=2,0!=1;

#include<stdio.h>
int func(int n){
    if(n=0)
        return 1;
    int i, c = 1;
    for (i = 1; i <= n;i++){
        c *= i;
    }
    return c;
}
float f(int n){
    float temp, fsum = 0.0;
    int i = 2;
    while(i<=n){
        temp = i * 1.0 / ((i + 1) * func(i - 2));//每一项的值
        fsum += temp;//求和
        i++;
    }
    return fsum;
}
int main(){
    printf("%f", f(5));
}

8,编写函数,实现sinx的的近似值

#include<stdio.h>
#include<math.h>
int func(int n){
    int i, c = 1;
    for (i = 1; i <= n;i++){
        c *= i;
    }
    return c;
}
int main(){
    int x, n, sign=1;
    double term, s = 0;
    int func(int n);//定义阶乘函数
    scanf("%d", &x);
    term = x;
    for (n = 1; term > 5e-6;n+=2){
        term = pow(x, n) / func(n); // 每次项数
        s = s + sign * term;
        sign = -sign;
    }
    printf("sin%d的近似值为:%10.8f", x, s);
    return 0;
}

9,编写函数计算,X-(X²/2!)+(X³/3!),当第K项满足|tk|<=e的负三次幂

#include <stdio.h>
#include <math.h>
double calculate(double x) {
    double t = x;
    double sum = t;
    int k = 2;
    double e = pow(e, -3);
    while (fabs(t) > e) {
        t = -t * x * x / (k * (k + 1));
        sum += t;
        k += 2;
    }
    return sum;
}
int main() {
    double x;
    printf("请输入x的值: ");
    scanf("%lf", &x);
    double result = calculate(x);
    printf("Result: %lf\n", result);
    return 0;
}

10,编写一个函数,计算X-(X²/2!)+(X³/3!)……(-1)n-1次幂X的n次幂/n阶乘

#include <stdio.h>
double factorial(int n) {
    double res = 1.0;
    for (int i = 1; i <= n; i++) {
        res *= i;
    }
    return res;
}
double power(double x, int n) {
    double res = 1.0;
    for (int i = 1; i <= n; i++) {
        res *= x;
    }
    return res;
}
double series_sum(double x, int n) {
    double sum = 0.0;
    for (int i = 1; i <= n; i++) {
        double term = power(x, i) / factorial(i);
        if (i % 2 == 0) {
            term = -term;
        }
        sum += term;
    }
    return sum;
}
int main() {
    double x;
    int n;
    printf("请输入X和n:");
    scanf("%lf %d", &x, &n);
    printf("前%d项的和为:%.2lf\n", n, series_sum(x, n));
    return 0;
}

11,编写函数计算数列,S(n)=1-1/2+1/3-1/4的前n项和

#include <stdio.h>
double CalculateSeries(int n) {
    double sum = 0.0;
    int sign = 1;
    for (int i = 1; i <= n; i++) {
        sum += sign * 1.0 / i;
        sign = -sign;
    }
    return sum;
}
int main() {
    int n;
    printf("请输入n的值:");
    scanf("%d", &n);
    printf("数列前%d项和为:%.6f\n", n, CalculateSeries(n));
    return 0;
}

12,编写函数计算Hermite多项式的第n项值

#include <stdio.h>
int hermite(int n, int x) {
  if (n <= 0) {
    return 1;
  } else if (n == 1) {
    return 2 * x;
  } else {
    return 2 * x * hermite(n - 1, x) - 2 * (n - 1) * hermite(n - 2, x);
  }
}
int main() {
  int n, x, result;
  printf("请输入x和n的值:");
  scanf("%d%d", &x,&n);
  result = hermite(n, x);
  printf("H(%d,%d) = %d", n, x, result);
  return 0;
}

13,已知sinx的泰勒展开式,编写程序求sinx的近似值,要求误差小于10的-8次幂

#include <stdio.h>
#include <math.h>
double taylor_sin(double x) {
    double term = x, sum = x, diff;
    int n = 1;
    do {
        term *= -x * x / ((2 * n) * (2 * n + 1));
        diff = term / sum;
        sum += term;
        n++;
    } while (fabs(diff) >= 1e-8);
    return sum;
}
int main() {
    double x, sinx;
    printf("请输入x的值:");
    scanf("%lf", &x);
    sinx = taylor_sin(x);
    printf("sin(%.15f)的近似值为%.15f\n", x, sinx);
    return 0;
}

14,给定一个正整数N,由所有分母小于或等于N的最简真分数按从大到小组成一个序列,例如N=5

1/5  1/4  2/5  1/2  3/5  2/3  3/4  4/5,编写函数输出序列

#include <stdio.h>

int gcd(int a, int b) { // 求a和b的最大公约数
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

int main() {
    int n, i, j, cnt = 0;
    scanf("%d", &n);
    int a[n * n][2]; // 用二维数组存储分数
    for (i = 1; i <= n; i++) {
        for (j = i + 1; j <= n; j++) {
            if (gcd(i, j) == 1) { // 如果i和j互质,即为最简分数
                a[cnt][0] = i;
                a[cnt][1] = j;
                cnt++;
            }
        }
    }
    // 冒泡排序,将分数从大到小排列
    for (i = 0; i < cnt - 1; i++) {
        for (j = 0; j < cnt - i - 1; j++) {
            if (a[j][0] * 1.0 / a[j][1] < a[j + 1][0] * 1.0 / a[j + 1][1]) {
                int temp0 = a[j][0], temp1 = a[j][1];
                a[j][0] = a[j + 1][0];
                a[j][1] = a[j + 1][1];
                a[j + 1][0] = temp0;
                a[j + 1][1] = temp1;
            }
        }
    }
    // 输出结果
    for (i = 0; i < cnt; i++) {
        printf("%d/%d ", a[i][0], a[i][1]);
    }
    printf("\n");
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值