目录
[题目4: 回调函数的选择题](#题目4: 回调函数的选择题)
题目1:左旋k个字符

思路1:
①左旋一个字符,只需要将a取出,剩下的元素依次前移,把a放到最后即可。

②将多个字符的旋转分化成第一个字符多次旋转。
③总结:先旋转一个字符,若有n个字符,则循环n次即可。
④后续可以优化,如果输入的n大于数组元素个数,就不用左旋。
代码1:
cpp
#include<stdio.h>
#include<string.h>
// 1.左旋字符串
void turnLeft(char* str,int n)
{
// 若n非常大,需要进行取模
n %= strlen(str);
// 旋转几个字符就循环几次
while (n--)
{
// 旋转第一个字符
char tmp = *str;
for (int i = 0; i < strlen(str) - 1;i++)
{
str[i] = str[i + 1];
}
str[strlen(str) - 1] = tmp;
}
}
int main()
{
char str[] = "ABCDE";
turnLeft(str, 3);
printf("%s\n", str);
}
思路2:
①将数组分成两个部分:旋转区域和非旋转区域。
②对这两个区域分别逆序。
③整体逆序,得到了旋转个字符的效果。

代码2:
cpp
#include<stdio.h>
#include<string.h>
void turnLeft_2(char* str, int n)
{
n %= strlen(str);
// 旋转区逆序
reverse_str(str, str + n - 1);
// 非旋转区逆序
reverse_str(str + n, str + strlen(str) - 1);
//整体逆序
reverse_str(str, str + strlen(str) - 1);
}
int main()
{
char str[] = "ABCDE";
turnLeft_2(str, 3);
printf("%s\n", str);
}
题目2:杨氏矩阵

思路:
要在二维数组中查询某个数,遍历即可,但是要求时间复杂度为O(N),就要思考一下了。
我们可以这样想:每次和二维数组右上角的数字进行比较,右上角的数字是本行最大的数字,如果比右上角的数字还要大,说明要查找的数字不在这一行,需要往下继续查找。

同理右上角的数字是同列最小的,如果待查找的数字是2,2 < 3,此刻2一定不在3那一列。
①设置行列初始值,从第0行,第2列(若是3*3的矩阵)开始;
②行不能大于2,列不能小于0;
③
(1)若num比右上角小,说明不在此列,需要列--;
(2)若num比右上角大,说明不在此行,需要行++;
(3)若以上都不成立,那么num就找到了,此时的col、row就是num的坐标。
代码:
cpp
#include<stdio.h>
#include<string.h>
void yanghuiSquare(int arr[3][3],int num)
{
// 从右上角开始
int col = 2;
int row = 0;
// 行坐标和列坐标的限制
while (row < 3 && col > 0)
{
// 不在这一行
if (num > arr[row][col])
{
row++;
}
else if (num < arr[row][col]) // 不在这一列
{
col--;
}
else
{
printf("%d的下标在(%d,%d)",num,row,col);
return;
}
}
printf("%d未在矩阵中找到\n", num);
}
int main()
{
int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
yanghuiSquare(arr,5);
}
题目3:指针选择题

答案:
C
A:这是一个数组,数组的每一个元素是一个函数指针,错误。
B:这是一个指针,指向一个函数,函数返回值是int[10],错误。
C:这是一个指针,去掉(*p)剩下int(*[10])(int),这是一个数组有10个元素,每一个元素的类型是函数指针,形参为int*,正确。
D:这是一个指针,指向的是int ((int*)[10]),这是一个函数,错误。
题目4: 回调函数的选择题

答案:
D
回调函数是调用函数指针指向的函数。
题目5:判断左旋或右旋

思路1:
每次旋转一个字符之后需要和另外一个字符串比较, 如果相同那就直接返回并输出即可。
代码1:
cpp
#include<stdio.h>
#include<string.h>
int is_left(char s1[], char s2[])
{
int len1 = strlen(s1);
int len2 = strlen(s2);
int cnt = 0;
char* p = s1;
char tmparr[10] = { 0 };
strcpy(tmparr, s1);
// 长度不同,直接返回0
if (len1 != len2) return 0;
// s1每次左旋一个字符就判断是不是s2
for (int i = 0; i < len1; i++)
{
cnt++;
char tmp = s1[0];
for (int i = 0; i < len1 - 1; i++)
{
s1[i] = s1[i + 1];
}
s1[len1 - 1] = tmp;
// 左旋完毕判断
if (!strcmp(s1, s2))
{
printf("%s是由%s左旋%d次得到的!\n", s2, tmparr, cnt);
return 1;
}
}
}
int main()
{
char s1[] = { "abcdef" };
char s2[] = { "cdefab" };
is_left(s1, s2); // 判断s1左旋后能否得到s2
return 0;
}
思路2:
使用库函数来实现,在abcdef后面追加一个abcdef,如此一来abcdefabcdef涵盖了所有的子串,这时候只需要使用库函数来判断是否是子串即可!
代码2:
cpp
#include<stdio.h>
#include<string.h>
int is_left_2(char s1[], char s2[])
{
int len = strlen(s1);
strncat(s1,s1,len);
if (strstr(s1, s2))
{
printf("左旋能得到");
}
else
{
printf("左旋不能得到");
}
}
int main()
{
char s1[20] = { "abcdef" };
char s2[] = { "cdefab" };
is_left_2(s1, s2); // 判断s1左旋后能否得到s2
return 0;
}
注意:尽量不要使用strcat自己追加自己,这样会把\0覆盖可能导致死循环。
题目6:函数设计选择题(多选)

答案:
BD
B:数组名传参,数组名是首元素的地址,首元素的类型是char*,要存放它的地址类型应该是char**所以B正确;
D:形参实参一致,正确。

题目7:函数参数设计选择题

答案:
C
arr是首元素的地址,arr的首元素是一个一维数组,可以使用数组指针指向一个5个int类型的数组,选C
题目7:矩阵转置
描述


分析:
二维数组本身就是按序排列存储,我们按照行读取数组之后,只需要按照列输出即可。

需要按照列的取值作为外层循环,行的取值作为内层循环
cpp
#include <stdio.h>
int main() {
int n = 0;
int m = 0;
scanf("%d %d", &n, &m);
int arr[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &arr[i][j]);
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
printf("%d ",arr[j][i]);
}
printf("\n");
}
return 0;
}
题目8:上三角矩阵判定


分析:
我们注意到,下三角的区域的列索引小于行索引,所以我们只需要判断此区域的数值是否为0即可。
代码:
cpp
#include <stdio.h>
int main() {
int num = 0;
scanf("%d", &num);
int arr[num][num];
for (int i = 0; i < num; i++ ) {
for (int j = 0; j < num; j++ ) {
scanf("%d", &arr[i][j]);
}
}
int flag = 1;// 是上三角
for (int i = 0; i < num; i++ ) {
for (int j = 0; j < i; j++ ) { // 只遍历下三角区域
if( arr[i][j] !=0)
{
flag = 0;
break;
}
}
}
if(flag)
{
printf("YES");
}else
{
printf("NO");
}
return 0;
}
题目9:有序序列判断

分析:
这里的有序分为正序和降序,所以设置两个变量:flag1代表是否升序,flag2代表是否降序,一个有序的数列,要么是升序要么是降序,所以flag1和flag2只能有一个是1。
这里需要注意的是111112,这个数列,所以要分为三种情况,此时flag的和要小于等于1,等于一说明要么是正序要么是降序,小于1代表了全是相等的情况。
cpp
#include <stdio.h>
int main() {
int num = 0;
scanf("%d",&num);
int arr[num];
for (int i = 0; i < num; i++) {
scanf("%d",&arr[i]);
}
int flag_1 = 0;// 升序
int flag_2 = 0; // 降序
for (int i = 0; i < num - 1; i++) {
if(arr[i] < arr[i+1])
{
flag_1 = 1;
}else if(arr[i] > arr[i+1]){
flag_2 = 1;
}else
{
// 什么也不做
}
}
if((flag_1 + flag_2) <=1 )// 有序
{
printf("sorted");
}else {
printf("unsorted");
}
return 0;
}