86. ZigZag Conversion

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

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".

分析:把之字形读的字符串转变成成行读的字符串。 经分析可知:除了字符串的第0个元素,其他的(numRows-1)*2个元素为一组。

对于第0行来说,组成它的元素是第0个元素加上每组内的第(numRows-1)*2-1=numRows*2-3个元素;
对于第i行来说,组成它的元素是每组内的第(i-1)个元素和第(numRows-2)*2-(i-1)=(numRows-1)*2-i-1个元素;
对于最后最后一行也就是numRows-1行来说,组成它的元素是每组内的第numRows-2个元素。

注意:在做的时候要现在纸上多画几个例子找规律!!!

86. ZigZag Conversion_第1张图片

/**
	 * 把之字形读的字符串转变成成行读的字符串。 经分析可知:除了字符串的第0个元素,其他的(numRows-1)*2个元素为一组。
	 * 对于第0行来说,组成它的元素是第0个元素加上每组内的第(numRows-1)*2-1=numRows*2-3个元素;
	 * 对于第i行来说,组成它的元素是每组内的第(i-1)个元素和第(numRows-2)*2-(i-1)=(numRows-1)*2-i-1个元素;
	 * 对于最后最后一行也就是numRows-1行来说,组成它的元素是每组内的第numRows-2个元素。
	 * 
	 */
	public String convert(String s, int numRows) {
		int len = s.length();
		if (len <= 0) {
			return "";
		}
		if(numRows<2){
			return s;
		}
		/* 定义每组内包含的元素个数 */
		int gN = (numRows - 1) * 2;
		/* 新建缓冲字符串数组,用于存每行的元素 */
		StringBuffer[] sbArr = new StringBuffer[numRows];
		System.out.println("sbArr.length = "+sbArr.length);
		for (int i = 0; i < numRows; i++) {
			sbArr[i] = new StringBuffer();
		}
		sbArr[0].append(s.charAt(0));
		/* 先分组,然后把组内的各个元素分配到各个行 */
		int group = 1;
		for (; group < len - gN; group = group + gN) {
			System.out.println("每组内的元素"+s.substring(group,group+gN));
			sbArr[0].append(s.charAt(group + gN - 1));
			for (int i = 1; i < numRows - 1; i++) {
				sbArr[i].append(s.charAt(group + i - 1));
				sbArr[i].append(s.charAt(group + gN - i - 1));
			}
			sbArr[numRows - 1].append(s.charAt(group +numRows - 2));
		}
		/* 剩下最后的几个元素不够一组 */
		if (group < len) {
			if (group + gN - 1 < len) {
				sbArr[0].append(s.charAt(group + gN - 1));
			}

			for (int i = 1; i < numRows - 1; i++) {
				if (group + i - 1 < len) {
					sbArr[i].append(s.charAt(group + i - 1));
				}
				if (group + gN - i + 1 < len) {
					sbArr[i].append(s.charAt(group + gN - i - 1));
				}
			}
			if(group +numRows - 2<len){
				sbArr[numRows - 1].append(s.charAt(group +numRows - 2));
			}
			
		}
		/*组装最后返回的字符串*/
		for (int i = 1; i < numRows; i++) {
			sbArr[0].append(sbArr[i]);
		}
		
		return new String(sbArr[0]);
	}
86. ZigZag Conversion_第2张图片

/**
	 * 采用动态分组的概念,每次每个组内的第一个元素为当前行在当前组内的第一个元素。 
	 * 每组内有gN = (numRows - 1) * 2个元素。
	 * 对第0行和末行来说,取每组内的第0个元素即可。
	 * 对第i(不是首行也不是末行)行来说,取每组内的第0个元素和gN-2i个元素。
	 * 逐行为主拼接最后的结果。
	 */
	 public String convert2(String s, int numRows) {
		 StringBuffer sb = new StringBuffer();
		 int len = s.length();
	     if (len == 0 || numRows < 2) return s;
	     /* 定义每组内包含的元素个数 */
	     int gN = (numRows - 1) * 2; 
	     /*以行为主开始拼接最后的结果*/
	     for(int i=0;i<numRows;i++){
	    	 /*逐个分配组内在该行的字符*/
	    	 for(int j=i;j<len;j=j+gN){/*以当前行开始进行后续的分组,每组内有gN个元素*/
	    		 sb.append(s.charAt(j));
	    		 /*不是首行或末行的话就要再加上组内的第二个元素*/
	    		 if(i>0 && i<numRows-1){
	    			 int second = j+gN-2*i;
	    			 if(second < len){
	    				 sb.append(s.charAt(second));
	    			 }
	    		 }
	    	 }
	     }
	     return new String(sb);
	 }

你可能感兴趣的:(86. ZigZag Conversion)