- ベストアンサー
文字の桁を増やす方法。
$words = array("a","i","u","e","o"); これを、 a,i,u,e,oの次を aa,ai,au,ae,aoの次を aaa,aai,・・・aoa,aoi さらに次ぎは、aaaa,aaaaiと続けたいのですが、これがうまくまとまりません。 正確には、日本語ひらがなで、カウンターを作ったら、”あい”、”あか”とかなっておもしろいかなー、と思ったんですが、。 うまくできないでしょうか?
- みんなの回答 (9)
- 専門家の回答
質問者が選んだベストアンサー
というわけで#6の修正 ------------------------- $list='aiueo'; $lastIndex = length($list) -1; sub incStr($){ my $str = shift; my $len = length $str; my $carry=1; my ($pos, $i); for($i=0;$i<$len;$i++){ if($carry){ $pos=index($list, substr($str, -1-$i, 1)); if($pos == $lastIndex){ $carry=1; substr($str, -1-$i, 1)= substr($list, 0, 1); if($i == $len -1){ $str = substr($list, 0, 1) . $str; } } else { $carry=0; substr($str, -1-$i, 1) = substr($list, $pos + 1, 1); } } else { last; } } return $str; } #インクリメントのテスト $data="a"; for($i=0;$i<=155;$i++){ print $data . "\n"; $data=incStr($data); }
その他の回答 (8)
- steel_gray
- ベストアンサー率66% (1052/1578)
> #3は、0→あ になりませんね while($num){ ~ } を do{ ~ }while($num); に、するべきでした。 do-while はperlで使ったことなかったんで使えるか試すのを面倒がってしまいました。(カウンターだから 0 はいいかな、って勝手に決めて) 面白さで数値を文字にするなら数値→文字の変換に別の規則性を持たせてもいいかもしれませんね 0→れ 1→い 2→に … みたいに。 ほとんど意味を持たなくても、たまに 4649→よろしく になったらちょっと幸せかも。
お礼
そうなんですよねー。 普通のキリ番ゲットもあきられてきたなー、と。 なので、”あいあい”ゲット!とか、書き込んでくれたら、書きやすいしキリ番より数も多いし、その人のイメージもつかみやすいし、おもしろいかなー、と。 けっこう、私には難しく、勉強になりました。 大体、分かっていながら質問したのは、並列して違う人の書くスクリプトを見たかったからも、理由の一つです。 とても、参考&勉強、それにみなさんの丁寧な対応も見直さないといけないと思いました。では。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#6も間違ってました…orz。(自信ありにマークついてるし・)
お礼
やはり、ちょっと違ってましたか。 実行してみて、少し結果が変だったので、辞書片手にあくせくしてたんですが。 Perlなんて3ヶ月ぶりだし、俺の知らないローカルルールがあるのかな? 俺の引数や関数の使い方が違っているんだろうと、思ってました。 後で調べればいいや、と。(w 訂正、チェックしてみますね。感謝♪
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
というわけで、題意を満たす(aoの次がaaa)もの ------------------------------------------------ $list='aiueo'; $radix = length $list; sub n2s($){ my $num = shift; return substr($list, 0, 1) x ($num / $radix) . substr($list, $num % $radix, 1); } sub s2n($){ my $str = shift; my $len = length $str; return ($len - 1)*$radix + index($list, substr($str,-1,1)); }
お礼
やっぱり、プログラムに精通した方はいらっしゃるんですねー。 私は、Perlも時たまですが、6,7年、PHPも半年くらい使ってますが、未だに辞書片手なのと、今まであるスクリプトは作らないので、四苦八苦してます。 オリジナルを作って配布とかではなく、作るのが楽しいからなんですが。 いやはや、感謝感謝♪
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#3は、0→あ になりませんね
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
#2です。 #2は、題意を満たしてませんね。 ぼけてました、突っ込んでくれる人がいないので、自分ツッコミ。
お礼
いや、大丈夫です!! 自作のを使うか、数字から直接変換するかを悩んでいます。(w とりあえず、自作のはちょっとだけシェイプアップ&Perlに移植できました。 もともと、数字が文字になれば特に気にするつもりはありませんでした。 「配列や、上記に書いた方法以外にもあれば、教えてください。」と書くのも忘れてましたし。(w それを読み取れと言うのは、いささか無理があるし。 しかも見直したら、BLUEPIXYさんの敬称を忘れてました。 いやはや、BLUEPIXYさんに大感謝♪
- steel_gray
- ベストアンサー率66% (1052/1578)
こんな感じでしょうか。 #テスト用関数コール my $count = 10; $str = &NumToAiueo($count); print "\n$count = $str\n"; # 10 = うあ exit; # こっから数値→かな変換 sub NumToAiueo { my $num = shift; my @aiueo = qw|あ い う え お|; my $len = scalar @aiueo; my $result; while($num) { my $kai = int ( $num / $len); my $yo = $num - $kai * $len; $result = $aiueo[$yo] . $result; $num = ($num - $yo) / $len; } return $result; }
お礼
そういえば、スクリプト自体はPHPで作ったけど、カウンターにするならPerlの方が楽だなー。 これまた簡潔な、スクリプトありがとうございます。 せっかく自分で作ったスクリプトをまるまる変えたい気分になってきました。(w ただ、”あああ”がカウンター数の111とぞろ目の方が、おもしろいと言えばおもしろいけど、こっちの方が処理が軽そう。(w
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
質問者さんの問題は、 n進数→10進数 10進数→n進数 への変換の問題と同じです。 a,i,u,e,o が 0,1,2,3,4 に対応すると考えれば5進数の数値の相互変換と同じです。 だから、対応する記号を数値に置き換えて計算すればよいです。 Perlでも良いということなので、Perlでサンプルを作ってみました。 -------------------------------------------------------------------- use encoding 'shiftjis'; $list = 'あいうえお'; $radix = length $list; sub n2s($){ #数値を該当する文字列に変換する my $num = shift; my $str = ""; while($num>=$radix){ $str = substr($list, $num % $radix, 1) . $str; $num /= $radix; } $str = substr($list, $num, 1) . $str; return $str; } sub s2n($){ #文字列を該当する数値に変換する my $str = shift; my $len = length $str; my $i,$num; for($num=0,$i=0;$i<$len;$i++){ $num=$num * $radix + index($list, substr($str, $i, 1)); } return $num; } ----------------------------------------------------------------- $data = 'おお'; print n2s(s2n($data)+1);#文字を数値にして+1して文字に戻す とすれば、 いああ と表示されます。 日本語ひらがなを使う場合はPerl5.6以降で 英数字のみの場合は、特にバージョンに関係なく動くと思います。 英数字の場合はencodingの指定は必要ありません。 日本語の扱いで問題があるようなら use encoding 'utf8'; を使ってください。(ソースコードをUTF-8で記述するの意) なお、もともとPerlには文字列をインクリメントできる機能があります。 例えば、 $data="az"; とすると $data++; は、 ba になります
お礼
ははは、そうでした。 当初の目的を忘れてました。 カウンターの方は、一桁目、二桁目、三桁目、、、の数字を別々に管理して、一つずつ足して、配列の総数になったら0に戻し、一桁上を一つ追加するの繰り返しの処理でなんとかなりました。 BLUEPIXYから比べたら、長くよけいな処理もありそうですが。 0 => a => a.gif => あ 75 => ri => ri.gif => り 15 => ga => ga.gif => が 34 => to => to.gif => と で、No.1の方の回答にも書きましたが、アングラっぽい使い方の方。 今までは暗号はcryptを使ってたけど、これからはmd5とsubstrを使うようにします。 データはpl,php,cgiの拡張子のどれかにはしていたんですが、なんか怖くなりました。(w
- pon_kotu
- ベストアンサー率21% (8/38)
今回、質問者さんがやられたいことは以下のような方法で可能だと思います 1.文字列の最後の文字を配列と順に比較 2.同じ文字があったところで、配列のその次の文字と置き換える 3.2のときに同じ文字が配列の文字の最後の文字ならば文字列の一つ前の文字列に対して、1-3を再度繰り返す 4.繰り返していて、文字列の先頭まで達し、かつその先頭の文字が配列の最後の文字ならば、その文字を配列の最初の文字にして、さらに文字列最初(最後どちらでもいい)に配列の最初の文字を加える 例1 文字列=aiu 後ろの文字 u 文字 u にマッチするので、次の文字eで置き換える 結果文字列= aie 例2 文字列=eio 後ろの文字 o 文字 o にマッチするので、文字aで置き換える 一つ前の文字 i 文字 i にマッチするので、文字uで置き換える 結果文字列= eua 例3 文字列=oo 後ろの文字 o 文字 o にマッチするので、文字aで置き換える 一つ前の文字 o 文字 o にマッチするので、文字aで置き換える 文字列の先頭に来たので文字aを加える 結果文字列=aaa このような感じで、繰り返していけばお望みのものができるかと思います がんばってください
お礼
とてもわかりやすい解説ありがとうございますね♪
補足
まだ、桁の追加方法や、その辺の処理がピンと来てませんが、、、。 っていうか、むしろそっちが分からん。 一応、PHPでも、PerlでもOKです。 ふと、これってUG系のソフトに使えちゃいますか? いや、だったら早いJAVAやCで作るのが本流なんだろうけど。 あんまり詳しくは書かないけど、えーと解析とか?できるような気も。 利用法も限られるけど。 作って大丈夫っすかね? 面倒そうだから、やめようかなー。
お礼
これも自分なりの変更点をくわえれば、参考になりそうです。 3人、とても勉強になしましたよ。感謝、感謝♪