需求:将所给的字符串以“倒N型”输出,可以指定输出的行数
函数 String convert(String s, int numRows)
例如输入“abcdefghijklnmopqrstuvwxyz”,输出成3行;得到
a e i n q u y
bdfhjlmprtvxz
c g k o s w
下面是一个5行的例子
String s = "abcdefghijklnmopqrstuvwxyzabcdefghijklnmopqrstuvwxyzabcdefghijklnmopqrstuvwxyz";
a___i___q___y___g___o___w___e___n___u
b__hj__pr__xz__fh__mp__vx__df__lm__tv
c_g_k_o_s_w_a_e_i_n_q_u_y_c_g_k_o_s_w
df__lm__tv__bd__jl__rt__zb__hj__pr__xz
e___n___u___c___k___s___a___i___q___y
便于观察,用下划线代替空格;可以看到行末是没有空格的;
观察例子:
1.从0开始计数,第0行第0列是“a”;第4行第0列是“e”;把位于斜线的字母称为斜线位
2.完整列之间间隔为3,即5-2;对于3行的例子,间隔为1=3-2;2行的例子,间隔为0=2-2;间隔为numRows-2;
3.首行和尾行没有斜线位;观察编号,得知a到i之间间隔2*numRows-2;令zigSpace=2*numRows-2
4.对于空格数量,第0行字母之间有3个空格;第1行斜线位左边有2个空格,右边0个;
第2行斜线位左边1个空格,右边1个;第3行斜线位左边0个空格,右边2个
这里斜线位字符的位置是: 2*numRows-2 + j - 2*i(其中i为行数,j为该行第几个字符)
5.最后一列后面不再添加空格,可用游标是否越界来判断
代码中convertOneLine将结果成从左到右读成一行
1 /** 2 * @author Rust Fisher 3 * @version 1.0 4 */ 5 public class ZigZag { 6 /** 7 * @param s 8 * @param numRows 9 * @return The string that already sort 10 */ 11 public static String convert(String s, int numRows) { 12 if (numRows <= 1 || s.length() < numRows || s.length() < 3) { 13 return s; 14 } 15 String strResult = ""; 16 int zigSpace = 2*numRows - 2; 17 int zig = numRows - 2; 18 for (int i = 0; i < numRows; i++) { 19 for (int j = i; j < s.length(); j+=zigSpace) { 20 strResult = strResult + s.charAt(j); 21 if (i != 0 && i != numRows - 1 && (zigSpace + j - 2*i) < s.length()) { 22 for (int inner = 0; inner < zig - i; inner++) { 23 strResult += " "; 24 } 25 strResult = strResult + s.charAt(zigSpace + j - 2*i); 26 if ((2*zigSpace + j - 2*i) <= s.length()/*true*/) {//control the final word of string 27 for (int inner = 0; inner < i - 1; inner++) { 28 strResult += " "; 29 } 30 } 31 } else { 32 if (j+zigSpace < s.length()) {//control the final word of per line 33 for (int outline = 0; outline < zig; outline++) { 34 strResult += " "; 35 } 36 } 37 } 38 } 39 if (i < numRows - 1) { 40 strResult += "\n"; 41 } 42 } 43 return strResult; 44 } 45 /** 46 * @param s 47 * @param numRows 48 * @return one line String 49 */ 50 public static String convertOneLine(String s, int numRows) { 51 if (numRows <= 1 || s.length() < numRows || s.length() < 3) { 52 return s; 53 } 54 String strResult = ""; 55 int zigSpace = 2*numRows - 2; 56 for (int i = 0; i < numRows; i++) { 57 for (int j = i; j < s.length(); j+=zigSpace) { 58 strResult = strResult + s.charAt(j); 59 if (i != 0 && i != numRows - 1 && (zigSpace + j - 2*i) < s.length()) { 60 strResult = strResult + s.charAt(zigSpace + j - 2*i); 61 } 62 } 63 } 64 return strResult; 65 } 66 public static void main(String args[]){ 67 String s = "abcdefghijklnmopqrstuvwxyzabcdefghijklnmopqrstuvwxyzabcdefghijklnmopqrstuvwxyz"; 68 String ss = "abcdefghijklnmopqrstuvwxyz"; 69 System.out.println(convert(ss,3)); 70 System.out.println(convertOneLine(ss,3)); 71 System.out.println(); 72 System.out.println(convert(s,5)); 73 System.out.println(convertOneLine(s,5)); 74 } 75 }
输出:
a e i n q u y
bdfhjlmprtvxz
c g k o s w
aeinquybdfhjlmprtvxzcgkosw
a i q y g o w e n u
b hj pr xz fh mp vx df lm tv
c g k o s w a e i n q u y c g k o s w
df lm tv bd jl rt zb hj pr xz
e n u c k s a i q y
aiqygowenubhjprxzfhmpvxdflmtvcgkoswaeinquycgkoswdflmtvbdjlrtzbhjprxzenucksaiqy
但不得不说明的是,上面这种方法太慢了。在网上查到了另一个方法,Java代码如下:
public String convert(String s, int numRows) { if (s == null || numRows < 1) return null; if (numRows == 1) return s; char[] ss = s.toCharArray(); StringBuilder[] strings = new StringBuilder[numRows]; for (int i = 0; i < strings.length; i++) { strings[i] = new StringBuilder(); } int zigNum = 2 * numRows - 2; for (int i = 0; i < s.length(); i++) { int mod = i % zigNum; if (mod >= numRows) { strings[2*numRows - mod - 2].append(ss[i]); } else { strings[mod].append(ss[i]); } } for (int i = 1; i < strings.length; i++) { strings[0].append(strings[i].toString()); } return strings[0].toString(); }
利用了StringBuilder类来构建String