忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2017/10/19 23:46 |
「Excel列名変換問題」をPHPで解く
http://blog.jnito.com/entry/20111102/1320253815
http://blog.jnito.com/entry/20111231/1325304733

数値とExcelのA1参照形式を相互変換する問題。

上限無しとかいう制限が入っていますが、とりあえず普通にintの範囲で記述します。
あちらの解答例もint越えを全く考慮してないので特に問題ないでしょう。

<?php
	class EXCEL{
	
		/**
		* Excelの列変換、数値から文字列に
		* @param int 「1」みたいな数値
		* @return String 「A」みたいな文字列
		*/
		public function getStr($input){
			$ret = '';
			do{
				$tmp = gmp_div_qr($input, 26);
				$input = gmp_intval($tmp[0]);
				$amari = gmp_intval($tmp[1]);
				// 割り切れる場合は0ではなく26として扱う
				if($amari === 0){
					$input--;
					$amari = 26;
				}
				$ret .= chr($amari+64);
			}while($input);
			
			return strrev($ret);
		}
		
		/**
		* Excelの列変換、文字列から数値に
		* @param String 「A」みたいな文字列
		* @return int 「1」みたいな数値
		*/
		public function getInt($input){
			$digit = strlen($input)-1;
			$ret = 0;
			for($i=0;$i<=$digit;$i++){
				$ret += (ord($input[$digit-$i])-64) * (26**$i);
			}
			return $ret;
		}
		
	}
	
	// 以下はテスト
	$test = [
		[1, 'A'],
		[2, 'B'],
		[3, 'C'],
		[25, 'Y'],
		[26, 'Z'],
		[27, 'AA'],
		[28, 'AB'],
		[51, 'AY'],
		[52, 'AZ'],
		[53, 'BA'],
		[54, 'BB'],
		[256, 'IV'],
		[16384, 'XFD'],
	];

	$excel = new EXCEL();
	foreach($test as $key=>$data){
		$answer = $excel->getStr($data[0]);
		if($answer !== $data[1]){
			print('えらー');
		}
	}
	foreach($test as $key=>$data){
		$answer = $excel->getInt($data[1]);
		if($answer !== $data[0]){
			print('えらー');
		}
	}

第1問第2問合わせても30分かかりませんでした。
つうか第2問のほうが簡単で5分くらいで終わったんだが。
まあPerlで解けと言われたら解けませんけどね。

考え方は簡単で、単に26で割っていくだけです。
26で割り切れる場合だけ注意が必要ですが、それ以外は単純にchr()で数値文字を変換すればいいです。
逆に数値にする場合は、26の例外すらも一切不要です。
何の問題もなく完成。

しかしまあ$amariはないな。
PR


2014/06/13 23:32 | Comments(0) | PHP

コメント

コメントを投稿する






Vodafone絵文字 i-mode絵文字 Ezweb絵文字 (絵文字)



<<買ったものリスト 2014/06/15 | HOME | DoctrineのDISTINCTは正しく動作しない>>
忍者ブログ[PR]