通过本文,你将学到如何简单地优化算法和编程的基本方法-----套用,同时,你将更加理解字符串。
先从一个整型数组的颠倒说起
假设有(int []){1,2,3,4,5},要将它变成(int []){5,4,3,2,1},该怎么办?这就是我们今天要探究的数组颠倒问题。虽然这个东西似乎没什么太大用处,但对于提高编程能力有一定帮助。我们先通过一个图来分析如何颠倒一个整型数组。
将左边的数组按照线段的指示依次调换线段端点指向的元素,就可以变成右边的数组。由于整型数组每一个元素都是普通的(不像字符串那样用' '结尾)。所以对于整型数组的颠倒就十分容易。我们现在来设计算法。
直接由上图得出,我们需要用两个变量来表示线段的两端。对于奇数个元素的数组,我们这样编写类C伪代码:
for(i = 0 , j = SIZE - 1; i != j; i++, j--)
temp = array[i];
array[i] = array[j];
array[j] = temp;
对于偶数个元素的数组,我们这样编写类C伪代码:
for(i = 0, j = SIZE - 1; i < j; i++, j--)
temp = array[i];
array[i] = array[j];
array[j] = temp;
优化之后,我们发现 j = SIZE - i - 1 ,i < SIZE / 2而且当元素个数为偶数个时,i 不会等于 j 。综合后得出代码:
#include <stdio.h> #include <stdlib.h> #define SIZE 10 int main(int argc, char * argv[]){ int i, temp, array[SIZE] = {1,2,3,4,5,6,7,8,9,10}; for(i = 0; i < SIZE / 2; i++){ temp = array[i]; array[i] = array[SIZE - i - 1]; array[SIZE - i - 1] = temp; } for(i = 0; i < SIZE; i++) printf("%d ",array[i]); getch(); return 0; }
运行结果:
颠倒字符串!!!
我们已经比较了解字符串了(我的上一篇随笔介绍得比较详细)。由于字符串是由字符加' '组成,相当于一个字符数组,所以也能进行颠倒操作。如果你把上面用来颠倒整型数组的代码直接用在字符串上,肯定会出错。我想说的是,整型数组它的每一个元素都是普通的,没有什么特殊意义,但是字符串有一种元素很特别,那就是内容为' '的元素,它标志着字符串的结束,也区别着字符数组和字符串。所以,如果按前面的思路去颠倒,试问字符串的第一个元素就是' '了,那后面的元素不就没有意义了吗?反而还会使程序不稳定,后续的代码可能会读错缓冲区。我们还是来看一张图,这样对后续的算法设计有很大帮助。
大彻大悟了吧?这也就是说,字符串颠倒实际上就是颠倒字符数组中元素内容为 前的所有元素构成的子数组。我们就可以简单地设计伪代码。
计算子数组大小
颠倒子数组
我们可以通过strlen()函数计算出这个字符串的长度,实际上就是计算出子数组的元素个数,然后再套用整型数组的颠倒方法来颠倒子数组。我打算自己设计一个测试这个子数组元素个数的过程。现在,完整的代码如下:
#include <stdio.h> #include <stdlib.h> #define SIZE 10 int main(int argc, char * argv[]){ char temp, st[SIZE] = "China"; int i,size; for(size = 0; st[size] != '