目录
好久不见,自从刷完剑指offer里面所有目前可以用C解决的题目吧之后,就在刷一些高校的题和华为机试题,一直在总结经验,今天给大家分享一下 我觉得很精彩的四个代码题,都是有一些思想在里面的
每日小细节也会陆续更新这些好题,保证大家一两分钟就会有收货
关注收藏不迷路哦

对输入的字符串进行加解密,并输出。
加密方法为:
当内容是英文字母时则用该英文字母的后一个字母替换,同时字母变换大小写,如字母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这些单独拎出来就可以
- //字符串加解密
- #include
- #include
- #include
- int main()
- {
- char arr[1001] = { '\0' }; //需要加密的
- char arr1[1001] = { '\0' }; //需要解密的
- while (scanf("%s%s",&arr,&arr1)==2)
- {
- int len = strlen(arr);
- int len1 = strlen(arr1);
- //
- for (int i = 0; i < len; i++)
- {
- if (isdigit(arr[i]))
- {
- if (arr[i] == '9')
- arr[i] = 0;
- else
- arr[i] += 1;
- }
- else if (isupper(arr[i]))
- {
- arr[i] = tolower(arr[i]);
- if (arr[i] == 'z')
- arr[i] = 'a';
- else
- arr[i] = arr[i] + 1;
- }
- else
- {
- arr[i] = toupper(arr[i]);
- if (arr[i] == 'Z')
- arr[i] = 'A';
- else
- arr[i] = arr[i] + 1;
- }
- }
- //
- for (int i = 0; i < len1; i++)
- {
- if (isdigit(arr1[i]))
- {
- if (arr1[i] == '0')
- arr[i] = 9;
- else
- arr[i] -= 1;
- }
- else if (isupper(arr1[i]))
- {
- arr1[i] = tolower(arr1[i]);
- if (arr1[i] == 'a')
- arr1[i] = 'z';
- else
- arr1[i] = arr1[i] - 1;
- }
- else
- {
- arr1[i] = toupper(arr1[i]);
- if (arr1[i] == 'A')
- arr1[i] = 'Z';
- else
- arr1[i] = arr1[i] - 1;
- }
- }
- printf("%s\n %s", arr,arr1);
- }
-
- }
注意这里我们把两个字符串初始化成'\0',只要我们不确定到底数组有多少元素,只知道一个范围,需要具体输入之后才知道 的时候,就可以这么做!!!会自动加上字符串的 \0
其次就是熟练的运用
islower,isupper,tolower,toupper,这些函数,还要注意他们的头文件

我们发现其实就是把每次把第一个字符单独拿来,然后剩下的字符全都前移一个位置,最后把刚才拿出来的字符放回最后一个位置
- void reverse(char* arr, int number,int ans)
- {
- ans %= number;
- while (ans--)
- {
- char tmp = arr[0];
- //把元素往前挪一个
- for (int j = 0; j
-1; j++) - {
- arr[j] = arr[j + 1];
- }
- arr[number -1] = tmp;
- }
- }
-
- int main()
- {
- char arr[50] = { 0 };
- gets(arr);
- int target = 0;
- scanf("%d", &target);
- int len = strlen(arr);
- reverse(arr, len,target);
- printf("%s\n", arr);
- }
但是这个真的好麻烦
万一给一个很长的字符串那就没什么运行的必要了
所以我们选择一个很巧妙的方法!!!!!!!!!!!!!!!
- //但是刚才那个方法有点麻烦
- void reverse(char* start, char* end)
-
- {
- while (end - start > 0)
- {
- char tmp = *start;
- *start = *end;
- *end = tmp;
- start++;
- end--;
- }
-
- }
- int main()
- {
- char arr[50] = { 0 };
- gets(arr);
- int target = 0;
- scanf("%d", &target);
- int len = strlen(arr);
- target %= len;
- reverse(arr, arr + target-1);
- reverse(arr + target, arr + len - 1);
- reverse(arr, arr + len - 1);
-
- printf("%s\n", arr);
- }
是不是有小可爱已经看出来了,我这个代码的意思
比如要旋转的次数是2 那我就把两个字符先倒序,把剩下的字符倒序
注意是原地倒序
最后再把整个字符串倒序!
倒序三次这个思想还是很重要的一定要掌握这个方法
其次就是把元素前移的方法很重要,下次再有类似的写法一定要倒写如流!!

(具体的代码题找不到了。。)
比如说这个二维数组
1 2 3
4 5 6
7 8 9
就是一个很简单的杨氏矩阵
我的第一思路是(0,0)和(2,2)分别是最小的最大的元素
先比较要找的元素和他俩的关系,但是然后中间过程就变得好麻烦........
其实完全没必要
只需要和(0,2)比较如果比他小,那么就还在第一行(这一行)里,只需要纵坐标--
如果比他大,那么就是下一行但是列数还是一致的
- 杨氏矩阵
-
- int juge(int arr[3][3], int x, int y, int target)
- {
- int i = 0;
- int j = y-1;
-
- while (i <= x-1 && j >= 0)
- {
- if (arr[i][j ] > target)
- j--;
- else if (arr[i][j ] == target)
- return 1;
- else
- i++;
- }
- return 0;
- }
- int main()
- {
- //int arr[10][10] = { 0 };
- int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
- int r = 3;
- int l = 3;
- int target = 0;
- scanf("%d", &target);
- //scanf("%d%d", &r, &l);
- /*for (int i = 0; i < r; i++)
- {
- for (int j = 1; j < l; j++)
- {
- scanf("%d", arr[i][j]);
- }
- }*/
- int ret=juge(arr, r, l,target);
- if (ret)
- printf("YES\n");
- else
- printf("NO\n");
- }
其实我这个写法只能看一下是不是真的在二维数组里面有这个元素
如果要求更加变态 如果找到了这个元素 返回坐标这么办???
- 不仅要告知是否找到,还要打印坐标
- 原来就有这个参数,但是我还是想把它改变之后返回来,所以用传参的方式
- 返回型参数
- void juge(int arr[3][3], int* x, int* y, int target)
- {
- int i = 0;
- int j = *y - 1;
- int flag = 0;
- while (i <= *x - 1 && j >= 0)
- {
- if (arr[i][j] > target)
- j--;
- else if (arr[i][j] == target)
- {
- flag = 1;
- *x = i;
- *y = j;
- break;
- }
- else
- i++;
- }
- if (!flag)
- {
- *x = -1;
- *y = -1;
- }
-
- }
- int main()
- {
- //int arr[10][10] = { 0 };
- int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
- int r = 3;
- int l = 3;
- int target = 0;
- scanf("%d", &target);
- //scanf("%d%d", &r, &l);
- /*for (int i = 0; i < r; i++)
- {
- for (int j = 1; j < l; j++)
- {
- scanf("%d", arr[i][j]);
- }
- }*/
- juge(arr, &r, &l, target);
- if (r==-1&&l==-1)
- printf("NO\n");
- else
- printf("YES %d %d\n",r,l);
- }
方法二里面的传参型函数的方法很重要
还有用一个标记当做一个标签,根据需要设置成1/-1
函数返回的参数根据需要选择是不是要接收,不是必须要接收的!

- 这个方法把字符抽象成数字储存在数组,每次加加就是记录个数,把min设置成数字最小的那个,最后就是只要比min大的就输入
- #include
- #include
- int main()
- {
- char arr[21] = { 0 };
- gets(arr);
- int b[26] = { 0 };
- int len = strlen(arr);
- int min = 0;
- for (int i = 0; i < len; i++)
- {
- b[arr[i] - 'a']++; //其实这个就是比正常的字母表顺序提前一个从0开始
- }
- min = b[arr[0] - 'a']; //把最小值设置为初始值
- for (int i = 0; i < len; i++)
- {
- if (b[arr[i] - 'a'] <= min)
- min = b[arr[i] - 'a'];
- }
- for (int i = 0; i < len; i++)
- {
- if (b[arr[i] - 'a'] > min)
- printf("%c", arr[i]);
- }
- }
b[arr[i] - 'a'] ++;
这个步骤的思路太太太重要了!!!!!!!!!!
arr[i] - 'a' 把字符转换成字母表顺序的数字
b[arr[i] - 'a'] 把数字放在数组b里面
b[arr[i] - 'a'] ++ 每+一次就是把这个字符的个数+1
创作不易,感谢收看!!!!!!!!!