LeetCode 6 ZigZag Conversion

新颖之处:使用了__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] = '\0';
    return ret;
}

int main(){
	int numRows;
	char s[1000];
	while(scanf("%s%d",&s,&numRows)!=EOF){
		puts(convert(s,numRows));
	}
	return 0;
}
posted @ 2017-04-11 23:34  ojnQ  阅读(80)  评论(0编辑  收藏  举报