6. ZigZag Conversion
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 NA P L S I I GY 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字形)的变换。变换形式如下所示:
A)行数为两行的情形:0 2 41 3 6B)行数为三行的情形:0 4 81 3 5 7 92 6 10C)行数为四行的情形: 0 6 121 5 7 11 132 4 8 10 143 9 15D)行数为七行的情形:第一行:0 12 24第二行:1 11 13 23 25第三行:2 10 14 22 26第四行:3 9 15 21 27第五行:4 8 16 20 28第六行:5 7 17 19 29第七行:6 18 30
观察上面情形可知:
1)第一行和最后一行两个元素之间的距离是:(行数 - 1)* 2
2)中间几行中第一个元素与第二个元素和第二个元素与第三个元素间的距离和是:(行数 - 1)* 2.
3)中间几行中第一个元素和第二个元素间的距离与第几行的关系:(行数-第几行)* 2.
4)中间几行中第二个元素和第三个元素间的距离与第几行的关系:(第几行 - 1) * 2.
故有getIndex()函数:
1)如果是每行的第一个元素,直接返回行数。
2)如果是第一行或者最后一行的除首元素外的下标获取:前一个元素的下标 + (行数 - 1)* 2
3)中间几行的偶数列的下标获取:前一元素的下标 + (行数-第几行)* 2
4)中间几行的奇数列的下标获取(除首元素):前一元素下标 + (第几行 - 1) * 2
注:
程序中行数由于是从零开始的的,所以程序中会有相差一的出入。
intgetIndex(int index, int cnt, int numRows, int flag){ if ( flag == 0 ) { return cnt; } else if ( cnt == 0 || cnt == numRows - 1 ) { index = index + ( numRows - 1) * 2; } else if ( flag % 2 != 0 ) { index = index + (numRows - 1 - cnt) * 2; } else if ( flag % 2 == 0 ) { index = index + cnt * 2; } return index;}char* convert(char* s, int numRows) { if ( *s == '\0' || numRows == 1 ) { return s; } int len = strlen(s); if ( len <= numRows ) { return s; } int add = 0; char rest[len + 1]; int cnt = 0; for ( cnt = 0; cnt < numRows; cnt++ ) { int index = 0; int flag = 0; index = getIndex(index, cnt, numRows, flag); while ( index < len ) { rest[add] = *(s + index); add += 1; flag += 1; index = getIndex(index, cnt, numRows, flag); } } rest[len] = '\0'; sprintf(s, "%s", rest); return s;}
逐行读取每个元素,存入rest结果集中。最后写会s,防止出现局部数组返回。