perlの比較、ループの使い方について質問です。
perlの初心者でperlを使っていろいろと勉強しているのですが、以下のような場合、簡単に書ける方法ってないでしょうか?
比較、ループなど調べてみたのですが、なかなか思うようにいきません。
よろしくお願いします。
なお、以下のスクリプトではエラーが出て動きませんが、その点は今回の説明の為ご了承願います。
my @hoge(1,10,100,1000,10000,100000,1000000);
my $no=☆ ←☆については1~5の間でランダムに設定します。
my(@test);
for (my $i=0; $i<$no; $i++) {
@test[$i]=@hoge[$i];
}
例えば$noが2の場合、@test[0]と@test[1]を比較(@test[0]<@test[1])して偽の場合は、エラーを出し、$noが3の場合、@test[0]と@test[1]と@test[2]を比較(@test[0]<@test[1]<@test[2])して偽の場合は、エラーを出し、$noが4の場合、@test[0]と@test[1]と@test[2]と@test[3]を比較(@test[0]<@test[1]<@test[2]<@test[3])して偽の場合は、エラーを出し……以下同じような感じで進めたいのですが、簡単な書き方ってないでしょうか?
if ($no==2){
unlss (@test[0]<@test[1]){エラー}
}elsif($no==3){
unless (@test[0]<@test[1]<@test[2]){エラー}
}elsif($no==4){
unless (@test[0]<@test[1]<@test[2]<@test[3]){エラー}
}
上記のような書き方となるかと思いますが、$noが2の場合、test配列に@test[2]と@test[3]が変数としてない為上記の書き方ではスクリプト自体エラーとなります。
説明が分かりにくい点については申し訳ありませんが、どなたかご教授願えないでしょうか。
よろしくお願いします。
No.3ベストアンサー
- 回答日時:
配列の要素が数値順に並んでいるか否かのチェックは grep を使って行うことができます。
次のコードは、すべての隣接する要素を数値比較し、直前の要素よりも小さい要素の添字を @small に入れるものです。my $hoge = (1, 10, 100, 50, 1000, 10000, 5000, 100000);
my @small = grep { $hoge[$_ - 1] > $hoge[$_] } 1 .. $#hoge;
print "$hoge[$_ -1] > $hoge[$_]\n" foreach @small;
範囲演算子の両側の数値を変えれば、部分配列もチェックできます。1 .. 3 とすれば先頭の4つを、3 .. 5 とすれば添字 2 から 5 までをチェックできます。また、grep は if や unless 条件部に置くことができます。次のコードは、$hoge[0] < $hoge[1] < $hoge[2] と同等の効果が得られます。
unless (grep { $hoge[$_ - 1] >= $hoge[$_] } 1 .. 2) {
# 数値順に並んでいるときの処理
} else {
# 数値順に並んでいないときの処理
}
丁寧にご教授いただきありがとうございます。
初心者な者で、理解に時間がかかりましたがようやく分かってきました。
ありがとうございました。
No.4
- 回答日時:
> my $hoge = (1, 10, 100, 50, 1000, 10000, 5000, 100000);
No3 です。すみませんが、1つ記述ミスがありました。以下のように訂正します。
my @hoge = (1, 10, 100, 50, 1000, 10000, 5000, 100000);
No.2
- 回答日時:
文法的なことはNo.1さんのご指摘の通りですが・・・・
たぶんきちんとした書籍を読んだ方がいいです.
ぜったいこんな書き方しない!っていう書き方が散見できますので
#my(@test) なんて普通は書かない・・・
#意図的にわざとすることがないとは言わないけど
次に,きちんと処理手順を考えましょう
要は $no の値に応じて,異なるものを比較して結果を出したいということでしょう
$no=2 => $test[0]<$test[1]
$no=3 => $test[0]<$test[1]<$test[2]
という具合に($no=1の場合のチェックは?).
となると,
(1) $noに応じて,比較対象を取り出す
(2) 取り出した比較対象を実際に比較する
(1)については配列の「スライス」をすればいいでしょう.
配列@testの0..$no-1の要素を取り出せばOK
(2)については@testの各要素が数字であるという条件で
今回のように「順番」であることを求めるならば
ソートを使えばいいでしょう.
@testの0..$no-1でできた配列の要素と,それを昇順で並べた配列の要素が
順番も含めて完全に一致していればクリア,そうでなければアウト
#この処理だと$noのときは常にクリアとなる
ついでにいえば,質問に書かれていることだけなら
@hogeからわざわざ@testをコピーする必要はないでしょう?
@hogeをそのまま使えばOKでは?
アルゴリズムの一例をあげました.
こういうののコツは
・if-elseを繰り返さない(一般に,同じことの繰り返しはしない方がいい)
・処理を細切れにして(一個の処理単位はできるだけ短く),
入口と出口を明確にして,それらをつなぎ合わせる
というようなことです.
具体的なコードはご自分でどうぞ.
「スライス」「ソート」「配列の比較」という
よくある処理の組み合わせです.
No.1
- 回答日時:
配列の要素を使用するときは
$test[0] と$を使うのが普通。
@test[0]は 0番目の要素からなるリスト。
この違いは場合によっては結構重要。
> $test[0]<$test[1]<$test[2]
Perlではこのような条件式の書き方はゆるされていません。
このような数学的な書き方は、プログラミング言語によって
1)そもそも文法エラーになる
2)書けるけど実行時にエラー
3)書けるけど意味が違う: a<b<c→a<bの真偽を表す値と cの比較(真偽が1/0なら 1<c または 0<c)
4)数学と同じ意味
となり、Perlでは1)、C言語では3)で、4)という言語はほとんどありません。
syntax error at XXX.pl line XX, near "] <"
とかいうエラーメッセージではなかったですか?(こちらではそうなりました)
これは「文法(syntax)間違い(error)」です。
>@test[2]と@test[3]が変数としてない為
のエラーではありません。そもそもPerlでは、使用してない添字を指定してもエラーは出ません。
a<b<c → a<b かつ b<c
という意味を明確に指定する必要があります
($test[0]<$test[1]) && ($test[1]<$test[2])
こう分けて考えれば
($test[0]<$test[1])
($test[1]<$test[2])
...
($test[i-1]<$test[i])
....
($test[n-1-1]<$test[n-1])
となることがわかります。これは、ループを使って簡単に書くことができます。
この回答への補足
早速ありがとうございます。
>配列の要素を使用するときは
>$test[0] と$を使うのが普通。
>@test[0]は 0番目の要素からなるリスト。
>この違いは場合によっては結構重要。
@を使っても$を使っても同じ事だと思ってたので、普通に@を使ってましたが…。
今後は$を使うようにします。
>$test[0]<$test[1]<$test[3]
こちらが文法エラーだったとは…。勉強不足です。
教えていただきありがとうございます。
>a<b<c → a<b かつ b<c
>という意味を明確に指定する必要があります
>($test[0]<$test[1]) && ($test[1]<$test[2])
>こう分けて考えれば
>($test[0]<$test[1])
>($test[1]<$test[2])
>...
>($test[i-1]<$test[i])
>....
>($test[n-1-1]<$test[n-1])
>となることがわかります。これは、ループを使って簡単に書くことができます。
($test[i-1]<$test[i])までは分かるのですが(例えば私が示した$i=2の場合,
$test[1]<$test[2]となる)、($test[n-1-1]<$test[n-1])のnとはどのような場合なのでしょうか。
またループについてですが、
for (1..3){
($test[i-1]<$test[i]);
}
のような感じかぁとは思うのですが、ここからどのように比較し真、偽を判別していくかがよく分かりません。
もしよろしければ、簡単にで結構ですので、ループから比較の書き方を教えていただけないでしょうか。
よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画像が表示でnull; this.src
-
テキストファイルで提出とは?
-
INDIRECT 横に再度抽出したい
-
アルファベットに付いて質問し...
-
Raspberry Pi
-
Perl 特定のフォルダ以外削除
-
Perl言語について。
-
ファイルをディレクトリ分配の...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
AI sisterとは、偽物の人ですか?
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlについて
-
perlのrequireの動き方について...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Can't use string ("0") as an ...
-
CからPerlへの変換がうまくいき...
-
Perlで参照のクリアの方法
-
Perl > Pyrhon || Ruby
-
サンプルの意味
-
perlの引数が不安定になります。
-
PerlでCSV形式のファイルの一部...
-
Perl ハッシュの値のリストをス...
-
perlについて
-
引数に配列かスカラーかどちら...
-
Perlの戻り値について
-
明示的なオブジェクトの削除
-
UWSCの終了の仕方
-
画面を強制的に再描画させる方法
-
VBのReturnの使い方
-
VBAで3秒だけ時間を止めたい
-
Escキーを押すと、中断する時と...
-
DoEventsが必要な理由について
-
VBAでの一時停止と再開の方法
-
DOSコマンドのループ内のTIMEコ...
おすすめ情報