The string "PAYPALISHIRING"
is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)
P A H N
A P L S I I G
Y I R
And then read line by line: "PAHNAPLSIIGYIR"
Write the code that will take a string and make this conversion given a number of rows:
string convert(string text, int nRows);
convert("PAYPALISHIRING", 3)
should return "PAHNAPLSIIGYIR"
.
问题很清晰了,只是官网的示例排版不太好,在纸上画下abcdedfg排版下就可以了。
这个问题似乎没有什么算法可以套用,比如动态规划、递归之类,只能是在纸上多用几个实例写几遍,找出规律:
直接上代码:
有几点自己想要提醒下:
1,每写一个函数,都要想想这个函数实现什么功能? 是怎么样实现的? 这里想到一个看代码的好思路:先搞明白这个函数是干嘛的,问题的定义是什么。如果叫你来实现,你会怎么实现? 然后再来看别人的函数具体实现过程,暗中和自己的代码比较下优缺点。而平时看代码,我是反的来的,先看函数的实现过程,然后再知道这个函数干嘛的。
2,要实现一个功能,先想清楚思路,着重考虑如果处在边界情况会发生什么? 比如我在首次写上面的函数时,第八行是这样的: if(numRows>=n) ,这有个大问题,如果numRows==1,那么程序会陷入死循环!
3,单元测试的必要性,第2点的死循环检测,就是利用下面的单元测试发现的。
#define FUNC zigPrint
void check(string s,int numRows,string expt)
{
string rlt = FUNC(s,numRows);
if(rlt==expt)
cout<<"check: "<<s<<" ,pass."<<endl;
else
cout<<"check: "<<s<<" ,faild. expt: "<<expt<<" rlt: "<<rlt<<endl;
}
int main()
{
check("abc",1,"abc"); //单元测试的必要性:一整就整出死循环了!
check("abc",2,"acb");
check("abc",0,"abc");
check("abc",-1,"abc");
check("abcdefghijk",100,"abcdefghijk");
check("abcdefghijk",1,"abcdefghijk");
check("abcdefghijk",2,"acegikbdfhj");
check("abcdefghijk",3,"aeibdfhjcgk");
check("abcdefghijk",4,"agbfhceikdj");
check("abcdefghijk",5,"aibhjcgkdfe");
check("abcdefghijk",6,"akbjcidhegf");
check("abcdefghijk",7,"abckdjeifhg");
check("abcdefghijk",8,"abcdekfjgih");
return 0;
}