新颖之处:使用了__builtin_expect(!!(x),0)引导预测分支条件
题解:找到规律即可,虽然我找的规律不是太好,显得很是丑陋....
1. 首先第一个字符肯定是加入答案中,然后间隔为 2*n-2
2. 除每一行首字符之外,第一个字符 t1 的位置为 d - i , 第二个字符 t2 = i + d , 然后下两个字符间隔为 d 不断寻找即可 。
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
// 不得不说我的代码太丑了 TAT
// __builtin__expect(long exp,long c); 用来引导gcc进行条件预测
// __builtin__expect(!!(x) , 1)
// __builtin__expect(!!(x) , 0)
// likely 代表x经常成立 加载分支条件内部代码
// unlikely 代表x不经常成立 加载分支条件内部代码
char* convert(char* s, int numRows) {
if (__builtin_expect(!!(numRows==1),0)) return s;
int len = strlen(s);
char* ret = (char*)malloc(len + 1);
int d = (numRows - 1) * 2;
int k = 0;
for (int i = 0; i < numRows; i++){
ret[k++] = s[i];
int t1 = d - i , t2 = i + d; // 相当于左边第一个和右边第一个
// 特判两种情况
// 1.如果t1 = t2 说明t1,t2会重复 因此只能赋值一个
// 2.如果到达最后一行t1,t2正好会相差d个位置
if (t1 == t2) t2 = 0x3f3f3f;
if (i == numRows - 1) t2 = 0x3f3f3f , t1 += d;
while (t1 < len || t2 < len){
if(t1 < len) ret[k++] = s[t1];
if(t2 < len) ret[k++] = s[t2];
t1 += d; t2 += d;
}
}
ret[len] = ' ';
return ret;
}
int main(){
int numRows;
char s[1000];
while(scanf("%s%d",&s,&numRows)!=EOF){
puts(convert(s,numRows));
}
return 0;
}