P A H N
A P L S I I G
Y 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".
所谓的ZigZag,就是以倒N型这样的:
具体来说就是:
关键是要会如何计算各个字符的位置,这就需要数学知识了,根据特殊推导出公式来。
主要是3个公式:
1 之字形行数为nRows,那么每次倒N重复样出现前的间隔字符为ziglen = nRows*2-2,如上图有8行,第一个倒N包含abcdefghijklmn,第二个倒N从接下来的o
开始,我们知道字符o与前面第一个倒N的首个字符位置相差正好ziglen;
2 第一行和最尾一行都是存放一个字符的,所以存储的字符为间隔为ziglen的字符
3 中间行是需要额外存储多一个字符的,存储的字符位置是: ziglen + j - 2*i(其中i为行数,j为该行第几个字符了)
代码:
char* convert(char* s, int numRows) {
int l=strlen(s);
if(l<3||l<=numRows||numRows<=1)return s;
int i,j;
char *p=(char *) malloc ((l+10)*sizeof(char));
memset(p,'a',sizeof(p));
int index=0;
int ziglen=2*numRows-2;
for(i=0;i<numRows;i++){
for(j=i;j<l;j+=ziglen)
{p[index++]=s[j];
if(i!=0&&i!=(numRows-1)&&(ziglen+j-2*i)<l)
p[index++]=s[ziglen+j-2*i];}
}
p[index]='\0';
return p;
}下面输出倒N型:
类似上面分析,只不过在输出时注意空格的输出:
1 之字形行数为nRows,那么每次倒N重复样出现前的间隔字符为ziglen = nRows*2-2,如上图有8行,第一个倒N包含abcdefghijklmn,第二个倒N从接下来的o
开始,我们知道字符o与前面第一个倒N的首个字符位置相差正好ziglen;
2 第一行和最尾一行都是存放一个字符的,所以存储的字符为间隔为ziglen的字符,两个非空字符之间相差zigspce=nRows-2个空格;
3 中间行是需要额外存储多一个字符的,存储的字符位置是: ziglen + j - 2*i(其中i为行数,j为该行第几个字符了)。当第一个非空字符靠近左边时,在第1-第zigspace-i列有空格;当靠近右边时有i-1个空格:
void dis(char* s, int numRows)
{ if(numRows==1)cout<<s;
int l=strlen(s);
if(l==0||numRows<1)cout<<"NONE";
int ziglen=2*numRows-2;
int zigspace=numRows-2;
int i,j,k;
for(i=0;i<numRows;i++){
for(j=i;j<l;j+=ziglen)
{cout<<s[j];
if(i!=0&&i!=numRows-1&&ziglen+j-2*i<l)
{ for(k=0;k<zigspace-i;k++)
cout<<" ";
cout<<s[ziglen+j-2*i];
for(k=0;k<i-1;k++)
cout<<" ";
}//中间行输出:先输出第一个,再是空格,最后还是N型上的字符
else
{for(k=0;k<zigspace;k++)
cout<<" ";
}//第一行和最后一行空格
}
cout<<endl; }
}
本文详细阐述了zigzag字符串转换算法的实现过程,包括关键公式推导与代码实现,帮助开发者理解并应用zigzag模式将字符串进行特定排列。

2万+

被折叠的 条评论
为什么被折叠?



