ForNext
Only Do What Only You Can Do
2.4. 文書情報の圧縮
VBScript
JScript
Perl
更新日 : 2008.12.26
use strict; #****************************************************************************** # 文書情報の圧縮 #****************************************************************************** my $c = ""; my $EOF = "\0\0"; my $NEWLINE = "\n"; my @buf = []; my $lastc = ""; my $nrep = 1; my $nsave = 0; my $RCODE = "\0"; my $MAXCHUNK = 255; my $THRESH = 4; for ($lastc = get_char(); $lastc ne $EOF; $lastc = $c) { # 違う文字が出てくるまで 読む for ($nrep = 1; ($c = get_char()) eq $lastc; $nrep++) { last if ($nrep >= $MAXCHUNK); } if ($nrep < $THRESH) { # 繰り返し回数が 閾値未満なら、バッファに ためる for ( ; $nrep > 0; $nrep--) { $nsave++; $buf[$nsave] = $lastc; # $MAXCHUNK 以上には、ためない put_buf() if ($nrep >= $MAXCHUNK); } } else { # 繰り返し回数が 閾値を超えたら、バッファ内容を出力 put_buf(); # 反復の目印 put_char($RCODE); # 繰り返される文字 put_char($lastc); # 繰り返す回数 put_char($nrep); put_char($RCODE); } } # 残りの バッファ内容を出力 put_buf(); #============================================================================== # バッファ内容を出力 #============================================================================== sub put_buf { if ($nsave > 0) { # 文字数 put_char($nsave); put_char($RCODE); # バッファ内容 my $i; for $i (1..$nsave) { put_char($buf[$i]); } } $nsave = 0; } #============================================================================== # 1文字 取得 #============================================================================== my $current_line = ""; my $pos = -1; sub get_char { my $char; # まだ読んでなかったら if ($current_line eq "") { # 1行読む $current_line = <STDIN>; # ファイルの終わりなら 終了 return $EOF if (!$current_line); # 改行コードを取り除く chomp($current_line); # 現在位置 クリア $pos = 0; } # 行の終わりに達したら if ($pos >= length($current_line)) { # 現在行 クリア $current_line = ""; # 行の終わりを 知らせる return $NEWLINE; } # 半角 / 全角 if (substr($current_line, $pos, 1) =~ /^[\x80-\xff]/) { # 2バイト取得 $char = substr($current_line, $pos, 2); $pos += 2; } else { # 1バイト取得 $char = substr($current_line, $pos, 1); $pos++; } return $char; } #============================================================================== # 1文字 出力 #============================================================================== my $buffer = ""; sub put_char { ($_) = @_; if ($_ eq $NEWLINE) { # 行の終わりなら 出力 print $buffer, "\n"; $buffer = ""; } else { # 行の終わりでなければ、バッファにためる $buffer .= $_; } }
PHP
更新日 : 2008.12.26
<?php #****************************************************************************** # TAB の 除去 #****************************************************************************** $c = ""; $EOF = "\0"; $current_line = ""; $pos = -1; $NEWLINE = "\n"; $buffer = ""; $TAB = "\t"; $BLANK = " "; $col = 0; $tabs = array(); $MAXCOL = 80; settab(); while (($c = get_char()) != $EOF) { if ($c == $NEWLINE) { put_char($c); $col = 0; } else if ($c == $TAB) { do { put_char($BLANK); $col++; } while (!tabpos($col)); } else { put_char($c); $col += strlen($c); } } #============================================================================== # TAB 位置 の 初期設定 #============================================================================== function settab() { global $MAXCOL; global $tabs; for ($i = 1; $i <= $MAXCOL; $i++) { $tabs[$i - 1] = ($i % 4 == 0); } } #============================================================================== # TAB 位置か? #============================================================================== function tabpos($col) { global $MAXCOL; global $tabs; if ($col > $MAXCOL) { for ($i = $MAXCOL + 1; $i <= $col; $i++) { $tabs[$i - 1] = ($i % 4 == 0); } } $MAXCOL = $col; return $tabs[$col - 1]; } #============================================================================== # 1文字 取得 #============================================================================== function get_char() { global $fp; global $EOF; global $current_line; global $pos; global $NEWLINE; $char = ""; # まだ読んでなかったら if ($current_line == "") { # まだ OPEN してなかったら if ($pos == -1) { $fp = fopen("php://stdin", "r"); } # 1行読む $current_line = fgets($fp); # ファイルの終わりなら 終了 if (feof($fp)) { fclose($fp); return $EOF; } # 改行コードを取り除く $current_line = rtrim($current_line, "\n\r"); # 現在位置 クリア $pos = 0; } # 行の終わりに達したら if ($pos >= strlen($current_line)) { # 現在行 クリア $current_line = ""; # 行の終わりを 知らせる return $NEWLINE; } # 半角 / 全角 if (mb_ereg('^[\x80-\xff]', substr($current_line, $pos, 1))) { # 2バイト取得 $char = substr($current_line, $pos, 2); $pos += 2; } else { # 1バイト取得 $char = substr($current_line, $pos, 1); $pos++; } return $char; } #============================================================================== # 1文字 出力 #============================================================================== function put_char($char) { global $NEWLINE; global $buffer; if ($char == $NEWLINE) { # 行の終わりなら 出力 echo $buffer, "\n"; $buffer = ""; } else { # 行の終わりでなければ、バッファにためる $buffer .= $char; } } ?>
Python
Ruby
更新日 : 2008.12.26
#****************************************************************************** # TAB の 除去 #****************************************************************************** #============================================================================== # 1文字 取得 #============================================================================== $current_line = [] $pos = -1 $NEWLINE = "\n" $EOF = "\0"; def get_char # まだ読んでなかったら if $current_line.size == 0 # 1行読む line = $stdin.gets # ファイルの終わりなら 終了 return $EOF unless line # 改行コードを取り除く line.chomp!; # 文字の配列に分解 $current_line = line.split(//s) # 現在位置 クリア $pos = 0; end # 行の終わりに達したら if $pos >= $current_line.size # 現在行 クリア $current_line = [] # 行の終わりを 知らせる return $NEWLINE; end char = $current_line[$pos] $pos += 1 return char end #============================================================================== # 1文字 出力 #============================================================================== $buffer = "" def put_char(char) if char == $NEWLINE # 行の終わりなら 出力 puts $buffer $buffer = "" else # 行の終わりでなければ、バッファにためる $buffer << char end end #============================================================================== # TAB 位置 の 初期設定 #============================================================================== $tabs = []; $MAXCOL = 80; def settab() for i in (1.. $MAXCOL) $tabs[i - 1] = (i % 4 == 0) end end #============================================================================== # TAB 位置か? #============================================================================== def tabpos(col) if (col > $MAXCOL) for i in (($MAXCOL + 1)..col) $tabs[i - 1] = (i % 4 == 0) end end $MAXCOL = col return $tabs[col - 1]; end #============================================================================== # TAB の 除去 #============================================================================== c = "" TAB = "\t" BLANK = " " col = 0 settab while (c = get_char) != $EOF if (c == $NEWLINE) put_char c col = 0 elsif (c == TAB) begin put_char BLANK col += 1 end until tabpos(col) else put_char c col += c.length end end