杨氏矩阵,字符串左旋,字符串旋转结果题目解析

简介: 杨氏矩阵,字符串左旋,字符串旋转结果题目解析

杨氏矩阵


题目要求:有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。

示例

分析:我们仔细分析,不难发现,对于杨氏矩阵老说,右上角和左下角的元素是有特点的。右上角的元素是一行中最大的,一列中最小的。左下角的元素是一行中最小的,是一列中最大的。所以我们可以从右上角或者左下角开始查找。比如:从右上角开始查找的时候,右上角的元素比我们要查找元素小,我们就可以去掉右上角元素所在的这一行;右上角的元素比我们要查找的元素大,我们就可以去掉右上角元素所在的这一列。然后依然找右上角的元素继续和要查找的元素与比较。这样每一次比较去掉一行或者去掉一列。这个查找效率是高于遍历数组元素的

代码实现:

1. #include <stdio.h>
2. 
3. int findnum(int a[][3], int x, int y, int f) //第一个参数的类型需要调整
4. {
5.  int i = 0, j = y - 1; //从右上角开始遍历
6.  while (j >= 0 && i < x)
7.  {
8.    if (a[i][j] < f) //比我大就向下
9.    {
10.       i++;
11.     }
12.     else if (a[i][j] > f) //比我小就向左
13.     {
14.       j--;
15.     }
16.     else
17.     {
18.       return 1;
19.     }
20.   }
21.   return 0;
22. }
23. 
24. int main()
25. {
26.   int a[][3] = { {1, 3, 5},
27.           {3, 5, 7}, 
28.           {5, 7, 9} }; //一个示例
29. 
30.   if (findnum(a, 3, 3, 2))
31.   {
32.     printf("It has been found!\n");
33.   }
34.   else
35.   {
36.     printf("It hasn't been found!\n");
37.   }
38. 
39.   return 0;
40. }

字符串左旋


题目要求:

实现一个函数,可以左旋字符串中的k个字符。

例如:

ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

分析:设计循环使其可以旋1次,然后让他执行n次是一个最简单的思路:

实现如下:

1. void leftRound(char * src, int time)
2. {
3.  int i, j, tmp;
4.   int len = strlen(src);
5. time %= len; //长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
6.  for (i = 0; i < time; i++) //执行k次的单次平移
7.  {
8.    tmp = src[0];
9.    for(j = 0; j < len - 1; j++) //单次平移
10.     {
11.       src[j] = src[j + 1];
12.     }
13.     src[j] = tmp;
14.   }
15. }

改进一

这个思路当然可以,但是一次一次转毕竟太麻烦,就不能一次到位么?

当然可以,我们可以选择拼接法,一次到位:

 

 

实现如下:

1. void leftRound(char * src, int time)
2. {
3.  int len = strlen(src);
4.  int pos = time % len; //断开位置的下标
5.  char tmp[256] = { 0 }; //更准确的话可以选择malloc len + 1个字节的空间来做这个tmp
6. 
7.  strcpy(tmp, src + pos); //先将后面的全部拷过来
8.  strncat(tmp, src, pos); //然后将前面几个接上
9.  strcpy(src, tmp); //最后拷回去
10. }

改进二:

改进一要用到一个数组形成的辅助空间,让人觉得有点不爽,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:

先将要左旋的前三个家伙逆序(CBADEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,

代码如下:

1. void reverse_part(char *str, int start, int end) //将字符串从start到end这一段逆序
2. {
3.  int i, j;
4.  char tmp;
5. 
6.  for (i = start, j = end; i < j; i++, j--)
7.  {
8.    tmp = str[i];
9.    str[i] = str[j];
10.     str[j] = tmp;
11.   }
12. }
13. 
14. void leftRound(char * src, int time)
15. {
16.   int len = strlen(src);
17.   int pos = time % len;
18.   reverse_part(src, 0, pos - 1); //逆序前段
19.   reverse_part(src, pos, len - 1); //逆序后段
20.   reverse_part(src, 0, len - 1); //整体逆序
21. }

字符串旋转结果


题目要求:

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

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

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

分析:

本题当然可以将所有旋转后的结果放到一个数组里,然后进行查找,但是这种做法既不好操作,也太费事,但是这题有一个很简单的做法:

其实ABCDE无论怎么旋,旋转后的所有结果,都包含在了ABCDEABCD这个字符串里了。

所以做法很简单,只需要将原字符串再来一遍接在后面,然后找一找待查找的字符串是不是两倍原字符串的子集即可。

1. int findRound(const char * src, char * find)
2. {
3.  char tmp[256] = { 0 }; //用一个辅助空间将原字符串做成两倍原字符串
4.  strcpy(tmp, src); //先拷贝一遍
5.  strcat(tmp, src); //再连接一遍
6.  return strstr(tmp, find) != NULL; //看看找不找得到
7. }

方法二:

只需要进行一一比较就好


1. #include<stdio.h>
2. #include<string.h>
3. 
4. 
5. void panduan(char* p1,char* p2,int len)
6. {
7.  int count = 0;
8.  int n = 0;
9.  for (n = 0; n < len; n++)
10.   {
11.     count = 0;
12.     int i = 0;
13.     for (i = 0; i <= n; i++)
14.     {
15.       if (*(p1 + i) == *(p2 + len - n - i-1))
16.       {
17. 
18.         count++;
19.       }
20.     }
21.     if (count == n + 1&& *(p1 + i+1) != *(p2 + len - n - i))
22.     {
23.       printf("%s左旋%d个字符得到%s", p1, count+1 , p2);
24.       break;
25.     }
26.   }
27.   if (count == 0)
28.   {
29.     printf("没有左旋");
30.   }
31. }
32. 
33. 
34. int main()
35. {
36.   char s1[10] = "abcd";
37.   char s2[10] = "dabc";
38.   gets(s1);
39.   gets(s2);
40.   int len = strlen(s1);
41.   panduan(s1, s2, len);
42.   return 0;
43. }

 

若有更多做题方法,题目讲解有误或还有不懂的地方,欢迎评论区留言或者私信!!!

相关文章
|
4天前
|
算法 测试技术 C#
【解析几何】 【多源路径】 【贪心】1520 最多的不重叠子字符串
【解析几何】 【多源路径】 【贪心】1520 最多的不重叠子字符串
|
4天前
|
JavaScript 前端开发 Java
|
4天前
|
存储 安全 C语言
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(下))
79 0
|
4天前
|
存储 C语言
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))
c语言进阶部分详解(详细解析字符串常用函数,并进行模拟实现(上))
68 0
|
7月前
|
测试技术 Python
软件测试|Python字符串拼接详细解析
软件测试|Python字符串拼接详细解析
79 0
|
4天前
|
SQL 缓存 JavaScript
深入解析JavaScript中的模板字符串
深入解析JavaScript中的模板字符串
15 1
|
4天前
|
弹性计算 运维 Shell
|
4天前
|
存储 NoSQL 安全
Redis入门到通关之数据结构解析-动态字符串SDS
Redis入门到通关之数据结构解析-动态字符串SDS
18 0
|
4天前
|
存储 测试技术
luatos 字符串与数组转换,解析hex数组
luatos 字符串与数组转换,解析hex数组
26 1
|
4天前
|
JSON 数据格式
gson自定义Type解析json数组字符串
gson自定义Type解析json数组字符串

推荐镜像

更多