• 【C语言】字符串加密解密,字符串左旋,杨氏矩阵,删除字符串中出现次数最少的字符


    目录

    1.字符串解密加密

    2.字符串左旋

    3.杨氏矩阵

    4.删除字符串中出现次数最少的字符


    好久不见,自从刷完剑指offer里面所有目前可以用C解决的题目吧之后,就在刷一些高校的题和华为机试题,一直在总结经验,今天给大家分享一下 我觉得很精彩的四个代码题,都是有一些思想在里面的

    每日小细节也会陆续更新这些好题,保证大家一两分钟就会有收货

    关注收藏不迷路哦

    1.字符串解密加密 

     

    描述

    对输入的字符串进行加解密,并输出。

    加密方法为:

    当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母a时则替换为B;字母Z时则替换为a;

    当内容是数字时则把该数字加1,如0替换1,1替换2,9替换0;

    其他字符不做变化。

    解密方法为加密的逆过程。

    数据范围:输入的两个字符串长度满足 1 \le n \le 1000 \1≤n≤1000  ,保证输入的字符串都是只由大小写字母或者数字组成

    其实我们发现这个没那么难,只是稍微麻烦一些

    只需要输入两个字符串,然后把z Z a A 0 9这些单独拎出来就可以

    1. //字符串加解密
    2. #include
    3. #include
    4. #include
    5. int main()
    6. {
    7. char arr[1001] = { '\0' }; //需要加密的
    8. char arr1[1001] = { '\0' }; //需要解密的
    9. while (scanf("%s%s",&arr,&arr1)==2)
    10. {
    11. int len = strlen(arr);
    12. int len1 = strlen(arr1);
    13. //
    14. for (int i = 0; i < len; i++)
    15. {
    16. if (isdigit(arr[i]))
    17. {
    18. if (arr[i] == '9')
    19. arr[i] = 0;
    20. else
    21. arr[i] += 1;
    22. }
    23. else if (isupper(arr[i]))
    24. {
    25. arr[i] = tolower(arr[i]);
    26. if (arr[i] == 'z')
    27. arr[i] = 'a';
    28. else
    29. arr[i] = arr[i] + 1;
    30. }
    31. else
    32. {
    33. arr[i] = toupper(arr[i]);
    34. if (arr[i] == 'Z')
    35. arr[i] = 'A';
    36. else
    37. arr[i] = arr[i] + 1;
    38. }
    39. }
    40. //
    41. for (int i = 0; i < len1; i++)
    42. {
    43. if (isdigit(arr1[i]))
    44. {
    45. if (arr1[i] == '0')
    46. arr[i] = 9;
    47. else
    48. arr[i] -= 1;
    49. }
    50. else if (isupper(arr1[i]))
    51. {
    52. arr1[i] = tolower(arr1[i]);
    53. if (arr1[i] == 'a')
    54. arr1[i] = 'z';
    55. else
    56. arr1[i] = arr1[i] - 1;
    57. }
    58. else
    59. {
    60. arr1[i] = toupper(arr1[i]);
    61. if (arr1[i] == 'A')
    62. arr1[i] = 'Z';
    63. else
    64. arr1[i] = arr1[i] - 1;
    65. }
    66. }
    67. printf("%s\n %s", arr,arr1);
    68. }
    69. }

     注意这里我们把两个字符串初始化成'\0',只要我们不确定到底数组有多少元素,只知道一个范围,需要具体输入之后才知道  的时候,就可以这么做!!!会自动加上字符串的 \0

    其次就是熟练的运用

    islower,isupper,tolower,toupper,这些函数,还要注意他们的头文件


     2.字符串左旋

     我们发现其实就是把每次把第一个字符单独拿来,然后剩下的字符全都前移一个位置,最后把刚才拿出来的字符放回最后一个位置

    1. void reverse(char* arr, int number,int ans)
    2. {
    3. ans %= number;
    4. while (ans--)
    5. {
    6. char tmp = arr[0];
    7. //把元素往前挪一个
    8. for (int j = 0; j -1; j++)
    9. {
    10. arr[j] = arr[j + 1];
    11. }
    12. arr[number -1] = tmp;
    13. }
    14. }
    15. int main()
    16. {
    17. char arr[50] = { 0 };
    18. gets(arr);
    19. int target = 0;
    20. scanf("%d", &target);
    21. int len = strlen(arr);
    22. reverse(arr, len,target);
    23. printf("%s\n", arr);
    24. }

    但是这个真的好麻烦

    万一给一个很长的字符串那就没什么运行的必要了

    所以我们选择一个很巧妙的方法!!!!!!!!!!!!!!!

    1. //但是刚才那个方法有点麻烦
    2. void reverse(char* start, char* end)
    3. {
    4. while (end - start > 0)
    5. {
    6. char tmp = *start;
    7. *start = *end;
    8. *end = tmp;
    9. start++;
    10. end--;
    11. }
    12. }
    13. int main()
    14. {
    15. char arr[50] = { 0 };
    16. gets(arr);
    17. int target = 0;
    18. scanf("%d", &target);
    19. int len = strlen(arr);
    20. target %= len;
    21. reverse(arr, arr + target-1);
    22. reverse(arr + target, arr + len - 1);
    23. reverse(arr, arr + len - 1);
    24. printf("%s\n", arr);
    25. }

    是不是有小可爱已经看出来了,我这个代码的意思

    比如要旋转的次数是2 那我就把两个字符先倒序,把剩下的字符倒序

    注意是原地倒序

    最后再把整个字符串倒序!

    倒序三次这个思想还是很重要的一定要掌握这个方法

    其次就是把元素前移的方法很重要,下次再有类似的写法一定要倒写如流!!


    3. 杨氏矩阵

    (具体的代码题找不到了。。)

    比如说这个二维数组

    1 2 3

    4 5 6

    7 8 9 

    就是一个很简单的杨氏矩阵

    我的第一思路是(0,0)和(2,2)分别是最小的最大的元素

    先比较要找的元素和他俩的关系,但是然后中间过程就变得好麻烦........

    其实完全没必要

    只需要和(0,2)比较如果比他小,那么就还在第一行(这一行)里,只需要纵坐标--

    如果比他大,那么就是下一行但是列数还是一致的

    1. 杨氏矩阵
    2. int juge(int arr[3][3], int x, int y, int target)
    3. {
    4. int i = 0;
    5. int j = y-1;
    6. while (i <= x-1 && j >= 0)
    7. {
    8. if (arr[i][j ] > target)
    9. j--;
    10. else if (arr[i][j ] == target)
    11. return 1;
    12. else
    13. i++;
    14. }
    15. return 0;
    16. }
    17. int main()
    18. {
    19. //int arr[10][10] = { 0 };
    20. int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    21. int r = 3;
    22. int l = 3;
    23. int target = 0;
    24. scanf("%d", &target);
    25. //scanf("%d%d", &r, &l);
    26. /*for (int i = 0; i < r; i++)
    27. {
    28. for (int j = 1; j < l; j++)
    29. {
    30. scanf("%d", arr[i][j]);
    31. }
    32. }*/
    33. int ret=juge(arr, r, l,target);
    34. if (ret)
    35. printf("YES\n");
    36. else
    37. printf("NO\n");
    38. }

    其实我这个写法只能看一下是不是真的在二维数组里面有这个元素

    如果要求更加变态 如果找到了这个元素 返回坐标这么办???

    1. 不仅要告知是否找到,还要打印坐标
    2. 原来就有这个参数,但是我还是想把它改变之后返回来,所以用传参的方式
    3. 返回型参数
    4. void juge(int arr[3][3], int* x, int* y, int target)
    5. {
    6. int i = 0;
    7. int j = *y - 1;
    8. int flag = 0;
    9. while (i <= *x - 1 && j >= 0)
    10. {
    11. if (arr[i][j] > target)
    12. j--;
    13. else if (arr[i][j] == target)
    14. {
    15. flag = 1;
    16. *x = i;
    17. *y = j;
    18. break;
    19. }
    20. else
    21. i++;
    22. }
    23. if (!flag)
    24. {
    25. *x = -1;
    26. *y = -1;
    27. }
    28. }
    29. int main()
    30. {
    31. //int arr[10][10] = { 0 };
    32. int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
    33. int r = 3;
    34. int l = 3;
    35. int target = 0;
    36. scanf("%d", &target);
    37. //scanf("%d%d", &r, &l);
    38. /*for (int i = 0; i < r; i++)
    39. {
    40. for (int j = 1; j < l; j++)
    41. {
    42. scanf("%d", arr[i][j]);
    43. }
    44. }*/
    45. juge(arr, &r, &l, target);
    46. if (r==-1&&l==-1)
    47. printf("NO\n");
    48. else
    49. printf("YES %d %d\n",r,l);
    50. }

    方法二里面的传参型函数的方法很重要

    还有用一个标记当做一个标签,根据需要设置成1/-1

    函数返回的参数根据需要选择是不是要接收,不是必须要接收的!


     4.删除字符串中出现次数最少的字符

     

    1. 这个方法把字符抽象成数字储存在数组,每次加加就是记录个数,把min设置成数字最小的那个,最后就是只要比min大的就输入
    2. #include
    3. #include
    4. int main()
    5. {
    6. char arr[21] = { 0 };
    7. gets(arr);
    8. int b[26] = { 0 };
    9. int len = strlen(arr);
    10. int min = 0;
    11. for (int i = 0; i < len; i++)
    12. {
    13. b[arr[i] - 'a']++; //其实这个就是比正常的字母表顺序提前一个从0开始
    14. }
    15. min = b[arr[0] - 'a']; //把最小值设置为初始值
    16. for (int i = 0; i < len; i++)
    17. {
    18. if (b[arr[i] - 'a'] <= min)
    19. min = b[arr[i] - 'a'];
    20. }
    21. for (int i = 0; i < len; i++)
    22. {
    23. if (b[arr[i] - 'a'] > min)
    24. printf("%c", arr[i]);
    25. }
    26. }

    b[arr[i] - 'a'] ++;

    这个步骤的思路太太太重要了!!!!!!!!!!

    arr[i] - 'a'             把字符转换成字母表顺序的数字

    b[arr[i] - 'a']         把数字放在数组b里面

    b[arr[i] - 'a'] ++    每+一次就是把这个字符的个数+1

     


    创作不易,感谢收看!!!!!!!!!

  • 相关阅读:
    【图像分类】2022-ConvMixer ICLR
    高德地图爬虫实践:Java多线程并发处理策略
    【数据结构】排序算法复杂度 及 稳定性分析 【图文详解】
    linux基本知识总结和shell的使用
    Vue.js 之 透传 Attributes
    Unity合规检测处理
    mongodb 实现两个集合的关联并分页查询
    [PAT练级笔记] Basic Level 1018 锤子剪刀布
    二进制间距
    黑客(网络安全)技术自学30天
  • 原文地址:https://blog.csdn.net/weixin_71138261/article/details/126878058