C语言习题

该博客围绕C和C++语言,列举了数9的个数、分数求和、求最大值等19个算法题目。涵盖递归、数组操作、字符串处理等多种类型,还给出了部分题目的解题思路,如字符串逆序的递归实现、利用指针打印数组内容等。

目录

1、数9的个数

2、分数求和

3、求最大值

4、乘法口诀表

4.1、题目内容:在屏幕上输出9*9乘法口诀表

4.2、题目内容:实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定如:输入9,输出9*9口诀表,输出12,输出12*12的乖法口诀表。

5、几个实参

6、字符串逆序(递归实现)

6.1函数做题

6.2递归做题

7、计算一个数的每位之和(递归实现)

8、递归实现n的k次方

9、交换数组

10、将浮点数转换为整数类型,要求四舍五入。

11.求sn = a + aa + aaa + aaaa + aaaaa的前5项之和,其中a是一个数字,

12.'写一个函数打印arr数组的内容,不使用数组下标,使用指针。arr是一个整型一维数组。

12.1方法一:直接利用循环

12.2方法二:利用两个指针,即while(头<尾)

13.求出0~1000之间的所有“水仙花数”并输出。(这里直接求出所有的这类型的数)

14.写一个函数,可以逆序一个字符串的内容

15.喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。

16.输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分

17.杨氏矩阵

1.非指针形式

2.指针形式

18.实现一个函数,可以左旋了符串中的k个字符。例如:ABCD左旋一个字符得到BCDA。ABCD左旋两个字符得到CDAB

1.移动做法

2.三步翻转法

19.写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

1.穷举法

2.类似于模式串匹配(主串AABCD5个字符怎么反转结果在这个串里都能找到AABCDAABCD,用子串去匹配)

1、数9的个数

题目内容:编写程序数一下1到100的所有整数中出现多少个数字9

#include<stdio.h>	
int main()
{//90 91 92 93 94 95 96 97 98 99 9 19 29 39 49 59 69 79 89 99
	int count = 0;
	for (int i = 0; i < 100; i++) {
		if (i / 10 == 9) {
			count++;
		}
		if (i % 10 == 9) {
			count++;
		}
	}
	printf("%d", count);
	return 0;
}

2、分数求和

题目内容:计算1/1-1/2+1/3-1/4+1/5...... + 1/99 - 1/100的值,打印出结果

#include<stdio.h>	
int main()
{//第一种解法
	double sum = 0.0;//设置为double 这样下面好操作
	for (int i = 1; i <= 100; i++) {
		if (i % 2 == 0) {
			sum -= 1.0 / i;
		}
		else
		{
			sum += 1.0 / i;
		}
	}
	printf("%lf\n", sum);
	return 0;
}
#include<stdio.h>	
int main()
{//第二种解法
	double sum = 0.0;//设置为double 这样下
	int flag = 1;
	for (int i = 1; i <= 100; i++) {
			sum += flag * 1.0 / i;
			flag = -flag;
	}
	printf("%lf\n", sum);
	return 0;
}

3、求最大值

题目内容:求10个整数中最大值长

#include<stdio.h>	
int main()
{//这种方法只适用于全是正整数来求最大值,如果出现负数就不对
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int max = 0;
	for (int i = 0; i < 10; i++) {
		if (arr[i] > max) {
			max = arr[i];
		}
	}
	printf("%d", max);
	return 0;
}

所以应该是在已知的数中选择一个数,然后进行比较,即让max等于数组中的某个值!

#include<stdio.h>	
int main()
{
	int arr[10] = { -1,2,3,-4,5,6,7,8,9,-10 };
	int max = arr[0];
	for (int i = 0; i < 10; i++) {
		if (arr[i] > max) {
			max = arr[i];
		}
	}
	printf("%d", max);
	return 0;
}

4、乘法口诀表

4.1、题目内容:在屏幕上输出9*9乘法口诀表
#include<stdio.h>	
int main()
{
	for (int i = 1; i <= 9; i++) {//行数
		for (int j = 1; j <= i; j++) {//列数
			printf("%d*%d=%2d ", i, j, i * j);//%2d有空格填充
		}
		printf("\n");
	}
	return 0;
}

4.2、题目内容:实现一个函数,打印乘法口诀表,口诀表的行数和列数自己指定如:输入9,输出9*9口诀表,输出12,输出12*12的乖法口诀表。
#include<stdio.h>	
int printf_table(int n) {
	int i = 0;
	int j = 0;
	for (i = 1; i <= n; i++) {
		for (j = 1; j <= i; j++) {
			printf("%d*%d=%-2d ", i, j, i * j);
		}
		printf("\n");
	}
}
int main()
{
	int n;
	scanf("%d", &n);
	printf_table(n);
	return 0;
}

5、几个实参

exec( (v1, v2), (v3, v4), v5,v6 );

(v1, v2), (v3, v4),其实就是逗号表达式,最后的结果就是最右边的结果。所以有4个实参

6、字符串逆序(递归实现)

题目内容:编写一个函数reverse_string(char * string)(递归实现)

实现:将参数字符串中的字符反向排列,不是逆序打印。

要求:不能使用C函数库中的字符串操作函数。

比如:char arr[] = "abcdef” ;逆序之后数组的内容变成: fedcba

6.1函数做题
#include<stdio.h>
//#include<string.h>//题目不让引用函数的做法
int my_strlen(char* s) {
	int count = 0;
	while(*s != '\0') {
		count++;
		s++;
	}
	return count;
}
void reverse_string(char* str) {
	int left = 0;
	int right = my_strlen(str) - 1; //题目不让引用函数的做法,int right = strlen(str) - 1;
	while (left < right) {
		char temp = str[left];//等价于char temp = *(str+left),因为数组传参实际上传的就是地址,str默认是首地址0,这里的left,right实际上就是下标
		str[left] = str[right];
		str[right] = temp;
		left++;
		right--;
	}
}
int main(){
	char arr[] = { "abcdef" };
	reverse_string(arr);
	printf("%s", &arr);
	return 0;
}

数组传的地址。在函数里直接修改的就是原数组,所以不用返回,直接void!

等价于

6.2递归做题
#include<stdio.h>
//#include<string.h>//题目不让引用函数的做法
int my_strlen(char* s) {
	int count = 0;
	while(*s != '\0') {
		count++;
		s++;
	}
	return count;
}
void reverse_string(char* str) {//递归
	char tmp = *str;//1
	int len = my_strlen(str);
	*str = *(str + len - 1);//2 
	*(str + len - 1) = '\0';//3
	if (my_strlen(str) >= 2) {
		reverse_string(str + 1);//4
	}
	*(str + len - 1) = tmp;//5
}
int main(){
	char arr[] = { "abcdef" };
	reverse_string(arr);
	printf("%s", &arr);
	return 0;
}

可看教程1时06分左右53. 函数作业讲解_哔哩哔哩_bilibili

7、计算一个数的每位之和(递归实现)

题目内容:写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19

输入:1729,输出:19

#include<stdio.h>
int DigitSum(int a) {
	if (a > 9) {
		return DigitSum(a / 10) + a % 10;
	}
	else
	{
		return a;
	}
}
int main(){
int num = 1729;
int sum = DigitSum(num);
printf("%d\n", sum);
	return 0;
}

8、递归实现n的k次方

题目内容:编写一个函数实现n的k次方,使用递归实现

#include<stdio.h>
double Pow(int n, int k) {//因为指数为负答案会是分数
	if (k == 0) {
		return 1;
	}
	else if (k > 0) {
		return n * Pow(n, k - 1);
	}
	else
		return 1.0 / (Pow(n, -k));
}
int main(){
	int n, k;
	scanf("%d %d", &n, &k);
	double ret = Pow(n, k);
	printf("%lf\n", ret);
	return 0;
}

9、交换数组

题目内容:将数组A中的内容和数组B中的内容进行交换。(数组一样大)

#include<stdio.h>
int main(){
	int a[] = { 1,3,5,7,9 };
	int b[] = { 2,4,6,8,10 };
	int sz = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < sz; i++) {
		int tmp = a[i];
		a[i] = b[i];
		b[i] = tmp;
	}
	for (int i = 0; i < sz; i++) {
		printf("%d ", a[i]);
	}
	printf("\n");
	for (int i = 0; i < sz; i++) 
	printf("%d ", b[i]);
		return 0;
}

10、将浮点数转换为整数类型,要求四舍五入。

将浮点数转换为整数类型,要求四舍五入。
输入描述:
    随机输入的浮点数
输出描述:
    四舍五入之后的整数
示例1
    输入:
    14.99

    输出:
    15
#include <iostream>
using namespace std;

int main() {
    float a;
    cin>>a;
    if(a>=0)
        cout<<int(a+0.5)<<endl;
    else
        cout<<int(a-0.5)<<endl;
}

!!利用+或者-0.5来实现舍还是入

11.-1>sizeof(0)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <math.h>

int main() {
    int i=0;//全局变量
    i--;

    if (i > sizeof(i)) {
        printf(">\n");
    }
    else
    {
        printf("<\n");
    }

    return 0;
}
//答案>



在C语言中,sizeof(i) 返回的是变量 i 的字节大小。通常,整数变量(如 int)的大小在大多数系统中是固定的,例如,在32位系统中通常为4字节,在64位系统中通常为8字节。

i 的值是-1,这是一个有符号整数。在计算机内部,负数通常以二进制的补码形式表示。当 -1 以补码形式表示时,在32位系统上,它会表示为32个1,而在64位系统上,它会表示为64个1。这意味着 -1 所占据的字节数与系统的位数有关,但它们都大于0。

原码:即最直接的二进制表示法,正数的原码与其二进制表示相同,而负数的原码是将正数的原码中的符号位取反。

    对于-1,原码是:10000001(假设是一个8位二进制数,最高位是符号位,0表示正数,1表示负数)。

反码:反码是将原码中的除符号位外的所有位取反(0变成1,1变成0)。

    对于-1,反码是:11111110。

补码:补码是在反码的基础上加1。

    对于-1,补码是:11111111。

因此,-1化为无符号整型是一个很大的整数。sizeof这个操作符,算出的结果的类型是unsigned int。无论是在32位系统还是64位系统上,sizeof(i) 都会返回一个正数(4/8),大于0。然后,你的条件语句 i > sizeof(i) 就变成了 -1 > 正数,因此条件为真。所以程序输出 > 表示为真。

这个结果可能会让人感到意外,因为通常认为负数小于正数,但在C语言中,条件表达式的结果是基于数据类型和大小,而不仅仅是数值大小。

11.求sn = a + aa + aaa + aaaa + aaaaa的前5项之和,其中a是一个数字,

例如:2 + 22 +222 + 2222 + 22222

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int a, n;
    scanf("%d%d", &a, &n);
    int i = 0;
    int sum = 0;
    int ret = 0;
    for (i; i < 5; i++)
    {
        ret = ret * 10 + a;
        sum = sum + ret ;
    }
    printf("%d", sum);
    return 0;
}

12.'写一个函数打印arr数组的内容,不使用数组下标,使用指针。arr是一个整型一维数组。

12.1方法一:直接利用循环
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int* p = arr;
    int sz = sizeof(arr) / sizeof(arr[0]);
    for (int i = 0; i < sz; i++) {

        printf("%d ", *(p + i));
    }
    return 0;
}

12.2方法二:利用两个指针,即while(头<尾)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
    int* p = arr;
    int sz = sizeof(arr) / sizeof(arr[0]);
    int* pend = arr + sz - 1;
    while(p<=pend) {
        printf("%d ", *p );
        p++;
    }
    return 0;
}

13.求出0~1000之间的所有“水仙花数”并输出。(这里直接求出所有的这类型的数)

“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如: 153=1 ^3+5^ 3+3^ 3,则153是一个“水仙花数”。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<math.h>
int main() {
    for (int i = 0; i < 100000; i++) {
        //计算位数
        int count = 1;
        int tmp = i;//假设123
        while (tmp / 10) {
            count++;
            tmp = tmp / 10;
        }
        //计算和
         tmp = i;
        int sum = 0;
        while (tmp) {
            sum += pow(tmp % 10, count);
            tmp = tmp / 10;
        }
        //判断
        if (sum == i) {
            printf("%d ",i);
        }
   }
    return 0;
}

14.写一个函数,可以逆序一个字符串的内容

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
void reserve(char* a) {
    
    int len = strlen(a);
    char* left = a;
    char* right = a + len - 1;
    while (left < right) {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        right--;
        left++;
    }
}
int main() {
    char arr[] = "abcdef";
    reserve(arr);
    printf("%s\n", arr);
    return 0;
}

15.喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以多少汽水(编程实现)。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	int money = 20;
	int drink = money;
	int drink_empty = money;
	while (drink_empty >= 2) {
		drink += drink_empty / 2;
		drink_empty = drink_empty / 2 + drink_empty % 2;//防止出现奇数,所以加上取模的这个
	}
	printf("%d", drink);

	return 0;
}

16.输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分

#include <stdio.h>

// 打印数组元素
void print(int arr[], int len) {
    for (int i = 0; i < len; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 移动奇数到数组前半部分,偶数到后半部分
void move(int arr[], int len) {
    int left = 0;
    int right = len - 1;
    while (left < right) {
        // 从前往后找一个偶数
        while ((left < right) && arr[left] % 2 == 1) {//这里还引入left<right的情况是因为万一数组全是奇数,没有判断条件,会越界
            left++;
        }
        // 从后往前找一个奇数
        while ((left < right) && arr[right] % 2 == 0) {
            right--;
        }
        if (left < right) {
            int tmp = arr[right];
            arr[right] = arr[left];
            arr[left] = tmp;
            right--;
            left++;
        }
    }
}

int main() {
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int sz = sizeof(arr) / sizeof(arr[0]);

    // 移动数组元素
    move(arr, sz);

    // 打印结果
    print(arr, sz);

    return 0;
}

17.杨氏矩阵

有一个数字矩阵,矩阵的每行从左到右是递增的.矩阵从上到下是递增的.请编写程序在这样的矩阵由真找某个数字是否存在.

要求:时间复杂度小于o(N);

1.非指针形式
#include <stdio.h>
int find(int arr[3][3], int r, int c, int k) {
    int x = 0;
    int y = c - 1;
    while (x<r&&y>=0)
    {
        if (arr[x][y] < k) {
            x++;
        }
        else if (arr[x][y] > k) {
            y--;
        }
        else
        {
            printf("下标是%d %d\n", x, y);
            return 1;
        }

    }
    return 0;
}
int main() {
   
    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    int k = 7;
    int ret = find(arr, 3, 3, k);
    if (ret == 1) {
        printf("找到了!\n");
    }
    else
    {
        printf("找不到!\n");
    }

    return 0;
}

2.指针形式
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int find(int arr[3][3], int *px, int *py, int k) {
    int x = 0;
    int y = *py - 1;
    while (x<*px &&y>=0)
    {
        if (arr[x][y] < k) {
            x++;
        }
        else if (arr[x][y] > k) {
            y--;
        }
        else
        {
            *px = x;
            *py = y;
            return 1;
        }

    }
    return 0;
}
int main() {
   
    int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    int k = 7;
    int x = 3;
    int y = 3;
    int ret = find(arr, &x, &y, k);
    if (ret == 1) {
        printf("找到了!\n");
        printf("下标是%d %d\n", x, y);
    }
    else
    {
        printf("找不到!\n");
    }

    return 0;
}

18.实现一个函数,可以左旋了符串中的k个字符。例如:ABCD左旋一个字符得到BCDA。ABCD左旋两个字符得到CDAB

1.移动做法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void left_move(char* str, int k) {
    int i = 0;
    int n = strlen(str);
    for (i = 0; i < k; i++) {
        char tmp = *str;
        int j = 0;
        for (j = 0; j < n - 1; j++) {
            *(str + j) = *(str + j + 1);
        }
        *(str + n - 1) = tmp;
    }
}
int main() {
   
    char arr[10] = "ABCDEF";
    int k = 2;//旋转几个字符
    left_move(arr, k);
    printf("%s\n", arr);
    return 0;
}

2.三步翻转法
#include <stdio.h>
void reverse(char* left, char* right) {
    while (left < right) {
        char tmp = *left;
        *left = *right;
        *right = tmp;
        left++;
        right--;

    }

}
void left_move(char* str, int k) {
    int n = strlen(str);
    reverse(str,(str+k-1));//左
    reverse((str+k),(str+n-1));//右
    reverse(str,(str+n-1));//整体

}
int main() {
   
    char arr[10] = "ABCDEF";
    int k = 2;//旋转几个字符
    left_move(arr, k);
    printf("%s\n", arr);
    return 0;
}

19.写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1=AABCD和s2=BCDAA,返回1。

给定s1 = abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

1.穷举法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int  left_move(char* str1, char *str2) {
    int i = 0;
    int n = strlen(str1);//5
    for (i = 0; i < n; i++) {
        char tmp = *str1;
        int j = 0;
        for (j = 0; j < n - 1; j++) {
            *(str1 + j) = *(str1 + j + 1);
        }
        *(str1 + n - 1) = tmp;
        if (strcmp(str1, str2) == 0) {
            return 0;
        }
    }
    return 0;
    
}
int main() {

    char arr1[] = "AABCD";
    char arr2[] = "BCDAA";
    int ret = left_move(arr1, arr2);
    if (ret == 1) {
        printf("yse\n");
    }
    else
        printf("no\n");
    return 0;
}

2.类似于模式串匹配(主串AABCD5个字符怎么反转结果在这个串里都能找到AABCDAABCD,用子串去匹配)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>+

//char arr[20] = "hello";
//strcat(arr, "bit");//hellobit
//
//strncat(arr, arr, 5);//hellohello

int  left_move(char* str1, char *str2) {
    //长度不相等,肯定不一样的
    if (strlen(str1) != strlen(str2)) {

        return 0;
    }
    //1.str1字符串的后面追加一个相同的str1
    int len = strlen(str1);
    strncat(str1, str1, len);
    //2.判断str2是否是str1的子串
    char* ret = strstr(str1, str2);
    if (ret == NULL) {
        return 0;
    }
    else
        return 1;

}
int main() {

    char arr1[] = "AABCD";
    char arr2[] = "BCDAA";
    int ret = left_move(arr1, arr2);
    if (ret == 1) {
        printf("yes\n");
    }
    else
        printf("no\n");
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值