题目大意
给定一个字符串,将其按照Z字形排列成给定行,逐行输出排列后的字符串。
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”.
分析
难点主要在于对问题的理解,尤其是对Z字形的理解,因为例子给的太少,我们对于Z字形的理解很容易错误,然后就是自己觉得哪哪都对,但是提交就是错误。
对于Z字形的理解
对于字符串abcdefghi
a g
b f h
c e i
d
为了方便理解同时避免巧合,我们使用上面的例子中的字符串排列成4行来分析(r即为参数中的nRows,这里为了方便书写):
PAYPALISHIRING共有14个字符,排列成4行后如下
P I N
A L S I G
Y A H R
P I
用其下标表示为:
0 6 12
1 5 7 11 13
2 4 8 10
3 9
观察可以发现,第一行和最后一行(r-1行)的字符下标为等差数列,差值为dif = 2*(r-1)。中间的行除了等差数列包含的字符外,还每两个数之间增加一个下标与前一个的差值为dif-2*i的字符。但是要注意判断是否超出字符串边界
代码
string convert(string s, int r) {
if(r<=1 || s.size()<r)
return s;
else{
int dif = 2*(r-1);
string re = "";
int l = s.size();
for(int i=0;i<r;i++){
for(int j=i;j<l;j+=dif){
if(i==0||i==r-1){
re+=s[j];
}
else{
re+=s[j];
if(j+dif-2*i<l){
re+=s[j+dif-2*i];
}
}
}
}
return re;
}
}