字符串Z字形变换是作者在经过自己研究,以及看了几篇博主的文章后(具体博主就不一一列举,感谢他们),自己觉得容易理解的方法写出来,供大家参考,方法有很多,这里仅仅只是本小白自己的理解,废话不多说,直接开始;
将一个给定字符串根据给定的行数,以从上往下、从左到右进行 Z 字形排列。
例1、比如输入字符串为 “LEETCODEISHIRING” ,行数为 3 时,排列如下:
L C I R
E T O E S I I G
E D H N
之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“LCIRETOESIIGEDHN”。
例2、同样,比如输入字符串为"LEETCODEISHIRING",行数为4时,排列如下:
L D R
E O E I I
E C I H N
T S G
之后,从左往右逐行读取,产生一个新的字符串,如:“LDREOEIIECIHNTSG”。
**方法:**这道题,我的方法是找规律,规律不好找,怎奈有心人啊,观察例1,我们可以发现,当numRows = 3时,我们会发现,排列后的图形中,第一行和最后一行每个元素之间的下标大小相差为:step=2*numRows-2;如图所示:
“L E E T C O D E I S H I R I N G”
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
上图可以看出,在给每个字符表明了下标之后,这个规律可以清晰的看到,新生成字符串的第一个字符“L”,下标是:0,第二个字符是:“C”,下标是:4;之间相差就是:step = 2numRows-2 = 23-2=4;正好符合规律,往后验证依然是如此,但是这个规律仅仅是限于第一行与最后一行,中间的行这个规律就不适用了。接下来我们看中间的行,我们假设行下标是从0开始,那么我们看第1行,第一个字符“E"的规律很好找,就是行下标,比如这是第1行,而“E”的下标如上图正好是1,同样以后每一行的开头字符的下标都正好是该行的下标,那么继续看第一行的第二个字符:“O”,我们看到他的下标是:5,通过我们发现规律:current +step-2*row(代码中的表示形式);然后下一个字符:“E”的坐标是7,计算方法为:current = current+step(代码的表示形式);现在所有的规律都找到了,看代码,以下的代码是用JAVA写的:
import java.util.*;
public class string_test {
public static void main(String[] args) {
System.out.println("请输入一个字符串:");
Scanner sc = new Scanner(System.in);
char[] arr = sc.nextLine().toCharArray();
String str = convert(arr,3);
System.out.println(str);
}
public static String convert(char[] s,int numRows) {
if(s == null || numRows == 0) {
return s.toString();
}
int step = 2*numRows-2;
int row = 0;
int current = 0;
int currentNeibor = 0;
StringBuffer sb = new StringBuffer(s.length);
for(int i=0;i<s.length;i+=step) {
sb.append(s[i]);
}
row++;
for(;row<numRows-1;row++) {
current = row;
while (current<s.length) {
sb.append(s[current]);
currentNeibor = current+step-2*row;
if(currentNeibor<s.length) {
sb.append(s[currentNeibor]);
}
current = current+step;/*这句代码放到这里的原因是需要先插入currentNeibor这个位置的字符,
然后在插入current+step这个位置的字符,也就是例子中的先插入"O"字符,在插入"E"字符*/
}
}
for(;row<s.length;row+=step) {
sb.append(s[row]);
}
return sb.toString();
}
}
运行结果如图所示:
到这里我们可以看到结果是我们所期望。(以上有何问题还请各位改正,谢谢!)