ZigZag - 曲折字符串

简介: 需求:将所给的字符串以“倒N型”输出,可以指定输出的行数函数 String convert(String s, int numRows)例如输入“abcdefghijklnmopqrstuvwxyz”,输出成3行;得到a e i n q u y bdfhjlmprtvxz c g k o s w ...

需求:将所给的字符串以“倒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

目录
相关文章
|
5月前
|
程序员
老程序员分享:LOJ10155数字转换
老程序员分享:LOJ10155数字转换
21 0
|
6月前
|
人工智能 算法 Java
每日一刷《剑指offer》字符串篇之编辑距离
每日一刷《剑指offer》字符串篇之编辑距离
63 0
每日一刷《剑指offer》字符串篇之编辑距离
【每日挠头算法(4)】字符串相加|字符串相乘
【每日挠头算法(4)】字符串相加|字符串相乘
|
存储 算法 C++
剑指offer(C++)-JZ46:把数字翻译成字符串(算法-动态规划)
剑指offer(C++)-JZ46:把数字翻译成字符串(算法-动态规划)
|
数据采集 存储 数据挖掘
【每周一坑】罗马数字转换
由图可知,螺旋数组中的数字运动方向依次 右 -> 下 -> 左 -> 上 -> 右 这样的循环,在合适的条件下变换累加方向即可。
|
算法 Python
【完虐算法】「字符串-最长公共前缀」5种方法脑洞大开
最近在专题制作过程中遇到了**最长前缀公共子串**的问题,也是读者最近校招面试到的一个题目。为什么拿出这个来说呢? 可怕的是,他居然给了 5 种解题方法。 更可怕的是,因此他直接少了一轮面试,天哪!!
388 0
【基础算法】浅浅刷个小题 # 找不同 # 字符串中的单词数 # 重新排列字符串 #
【基础算法】浅浅刷个小题 # 找不同 # 字符串中的单词数 # 重新排列字符串 #
|
开发者
傻傻分不清的进制与进制转换
傻傻分不清的进制与进制转换
386 0
傻傻分不清的进制与进制转换
|
机器学习/深度学习 算法 安全
【Python 百练成钢】时间调整、二进制数、回文素数、字母距离、CTF、Huffuman树、抽奖、前后缀最值、纯质数求解、花园灌溉
【Python 百练成钢】时间调整、二进制数、回文素数、字母距离、CTF、Huffuman树、抽奖、前后缀最值、纯质数求解、花园灌溉
222 0
【Python 百练成钢】时间调整、二进制数、回文素数、字母距离、CTF、Huffuman树、抽奖、前后缀最值、纯质数求解、花园灌溉
|
SQL 算法 搜索推荐
【边学边敲边记】LeetCode011:字符串相乘
【边学边敲边记】LeetCode011:字符串相乘
127 0
【边学边敲边记】LeetCode011:字符串相乘