6. Z 字形变换

52 阅读2分钟

6. Z 字形变换

中等

相关标签

premium lock icon相关企业

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 "PAYPALISHIRING" 行数为 3 时,排列如下:

P   A   H   N
A P L S I I G
Y   I   R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:"PAHNAPLSIIGYIR"

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

 

示例 1:

输入: s = "PAYPALISHIRING", numRows = 3
输出: "PAHNAPLSIIGYIR"

示例 2:

输入: s = "PAYPALISHIRING", numRows = 4
输出: "PINALSIGYAHRPI"
解释:
P     I    N
A   L S  I G
Y A   H R
P     I

示例 3:

输入: s = "A", numRows = 1
输出: "A"

 

提示:

  • 1 <= s.length <= 1000
  • s 由英文字母(小写和大写)、',' 和 '.' 组成
  • 1 <= numRows <= 1000
  • 4

题解:

宏定义使用方法:#define 宏名字 表达式

输出图形是周期规律的,找到下标间关联,模拟出输出结果。 模拟过程:获取每次Z字形最顶点的下标,行号为row的分别为顶点-row和顶点+row,处理一下row为0和row为行数的特殊情况会重复输出;除此之外,测试时候发现z边长为1有bug,所以应该处理z边长1的特殊情况,提前直接处理掉

两层循环过程:最外层循环:row循环;一层row内循环:通过周期t循环同一行的各个点

#include <stdio.h>
#include <stdlib.h>

#define toploc (numRows - 1) * 2 * t //顶点坐标宏定义为toploc

int main()
{
    int numRows;
    int i, size = 0;
    int row, t, point;
    char str[1000] = {'\0'};
    char ans[1000] = {'\0'};
    scanf("%s", str);
    scanf("%d", &numRows);
    if (numRows == 1) //1行在下面循环不符合规律,提前特殊处理
    {
        printf("%s", str);
        return 0;
    }

    for (i = 0;str[i];i ++)
    {
        size ++;
    }
    i = 0;
    t = 0;
    for (row = 0;row <= numRows - 1;row ++)
    {
        t = 0;
        while ((toploc - row >= 0 && toploc - row <= size - 1) || (toploc + row >= 0 && toploc + row <= size - 1))
        {
            if (toploc - row >= 0 && toploc - row <= size - 1)
            {
                ans[i] = str[toploc - row];
                i ++;
            }
            if (toploc + row >= 0 && toploc + row <= size - 1 && row != numRows - 1 && row != 0)
            //额外处理了row为0和row为numRows - 1的特殊情况,避免重复输出
            {
                ans[i] = str[toploc + row];
                i ++;
            }
            t ++;
        }
    }
    ans[i] = '\0';
    printf("%s", ans);
    return 0;
}