• ベストアンサー

Perl ランク

いつもお世話になっております。 ご教示お願い致します。 for ($i=0;$i<=10;$i++){ 処理 $Tensu } があります これを、 書き込み処理すると 80 60 70 40 50 20 20 100 30 90 となります。 目的としては 80,3 60,5 70,4 40,7 50,6 20,9 20,9 100,1 30,8 90,2 このときに 順位も付与させたいのですが、 どのようにするのでしょうか? ※順位は $Rankという変数に格納させたいです。

  • Perl
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • hok212
  • ベストアンサー率66% (100/150)
回答No.2

No.1 です。 よくよく見返したら、$PrevPointの扱いが間違っていました。 正しくは次の通りです。 #=====ここから===================================== $PrevPoint = -1; for ($i=0;$i<=10;$i++) { 処理 push(@Points,$Tensu); } foreach $point (@Points) { $Rank = &sortPoint($point); print $point . "," . $Rank . "\n"; } sub sortPoint() { @lines = sort { $b <=> $a } @Points; $i = 0; $tmp = 0; foreach $line (@lines) { $i++; if ($line == $_[0]) { if ($line == $PrevPoint) { $tmp = $i--; } else { $tmp = $i; } $PrevPoint = $line; last; } } return $tmp; } #=====ここまで=====================================

perlhogehoge
質問者

お礼

前回に引き続き、わかりやすい丁寧な御回答 感謝感激です;; 実行したいことが無事できました。 本当にありがとうございました!!!

その他の回答 (1)

  • hok212
  • ベストアンサー率66% (100/150)
回答No.1

変数$Tensuに20や90などの点数が入っているのなら、次の手法で出来ると思います。 # まずは配列@Pointsに点数を格納します for ($i=0;$i<=10;$i++) { 処理 push(@Points,$Tensu); } # 配列@Pointsをループ処理し、その都度 sortPoint ルーチンを呼び出す。 foreach $point (@Points) { $Rank = &sortPoint($point); print $point . "," . $Rank . "\n"; } # 配列@Pointsを降順で並び替え、その結果を配列@linesに格納 # $tmpが並び順の番号になるので、その値を呼び出し元に戻す sub sortPoint() { @lines = sort { $b <=> $a } @Points; $i = 0; $PrevPoint = -1; $tmp = 0; foreach $line (@lines) { $i++; if ($line == $_[0]) { if ($line == $PrevPoint) { $tmp = $i--; } else { $tmp = $i; } last; } } return $tmp; } $PrevPointの初期値を今回は「-1」に設定しましたが、ここは絶対にあり得ない数値を指定します。 点数なのでマイナス値はないだろうと仮定して -1 を設定しました。 sortPoint内の $_[0] が分かりにくいかもしれませんが、呼び出し元から渡された点数が入っています。

関連するQ&A

  • Perl 変数 連番 for

    いつもお世話になっております。 for文?の使い方を教えてほしいです。 my $test1 = $form->param('test1'); my $test2 = $form->param('test2'); my $test3 = $form->param('test3'); my $test4 = $form->param('test4'); my $test5 = $form->param('test5'); このようにtestは同じでその後ろに連番がついている場合の変数なのですが これが何十個もあれば、記述するのも管理するのも、少し面倒です。 それでfor文を利用し、 for ($i= 1; $i < 31; $i++){ この中の記述 } ソースを短縮したいのですが、 「この中の記述」がわかりません・・・ ご教示お願い致します。

    • ベストアンサー
    • Perl
  • 初心者向け配列の処理、本に載っているコードの意味が少しわかりません。

    入門者向けの本に載っていたコードなんですが、1行だけ どういった処理を行っているのか理解できないところがありました。 よろしくお願いします。 /* 5人の学生の点数を読み込んで60点以上の学生の一覧を表示 */ #include <stdio.h> #define NUMBER 5 /* 人数 */ int main(void) {    int i;    int snum = 0; /* 合格者の人数 */    int tensu[NUMBER]; /* NUMBER人の学生の点数 */    int succs[NUMBER]; /* 合格者リスト(合格者の添字を格納) */    puts("点数を入力してください。");    for (i = 0; i < NUMBER; i++) {       printf("%2d番:", i + 1);       scanf("%d", &tensu[i]);       if (tensu[i] >= 60)          succs[snum++] = i; /*ここがどういった処理になっているのかわからないです。 */    }    puts(" 合格者一覧 ");    puts("------------");    for (i = 0; i < snum; i++)       printf("%2d番(%3d点)\n", succs[i] + 1, tensu[succs[i]]);    return (0); }

  • String配列を扱うアルゴリズムについて

    よりパフォーマンスの良いアルゴリズムが、 ございましたらご教示下さい。 数レコード分のDBテーブルデータが格納されたString[][]型が存在するとします。 配列の要素は、String[行(フィールド)][列(カラム)]です。 ここで、全レコード中の列ごとの最大文字列長を int[]型に取得したいと思います。 そうした場合、自作した下記の処理よりも、 よいパフォーマンスを得られるアルゴリズムがございましたら、 ご教示願いたいと思います。 ※処理前提条件 ●String[][]型変数に、過不足無くテーブルデータが格納済みであるとします。 ●配列の第一(行)・第二(列)要素の最大値は取得済みであるとします。 ////////////// // 変数定義 // ////////////// String[][] tableData; ← テーブルデータ格納済み(過不足はありません) int 行数 = 全行数(取得済み); int 列数 = 全列数(取得済み); //列毎の最長文字列値を格納する。 int[] maxLen = new int[列数]; ////////// // 処理 // ////////// //列の個数分、処理を繰り返す for(int i = 0; i < 列数; i++) {   //行の個数分、処理を繰り返す   for(int j = 0; j < 行数; j++) {     //NULLを回避する     if(tableData[i][j] != null) {       //int配列に格納済みの数値より大きければ、改めて格納する       if(maxLen[i] < tableData[i][j].length()) {         maxLen[i] = tableData[i][j].length();       }     }   } } 以上です、どなかお知恵をお貸し頂けませんか。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • カレントディレクトリの取得

    お世話になります。 バッチファイルでの処理中にカレントディレクトリをフルパスで取得し 変数に値を格納したいのですが、やり方が分かりません。。 いろいろ調べた結果、カレントディレクトリの取得は「CD」 変数への格納は、「==」or「set」なのかな?ってぐらいの知識レベルです。 上記のコマンド以外でも構いませんので、カレントディレクトリを取得し 変数に値を格納する方法を、記述の仕方を含めてご教示くださいませ。 宜しくお願い致します。

  • インクリメントデータについて

    お世話になります。 for()ループ回数の値をCString へ格納したいです。 以下に検討しましたが、エラーになります。 CString Data; CString pp; for( int i=0; i<100; i++ ){ pp.Format(_T("%s"),i); Data += pp; } 求めたいのは、CString Data変数に for()のint iの回数分を インクリメントデータとして格納したいです。 Data = 0,1,2,3,4,5,・・・・99 のようなデータです。 どうぞよろしくお願い致します。

  • CString型の文字列連結について

    質問させて頂きます。 開発環境はVC++.netです。 CString型の文字列連結について教えて頂きたく。 CString Test[_MAX_FNAME+1]; という変数にがあるとします。 Test変数のデータは Test[0]には"2" Test[1]には"1" が格納されてるとします。 Test変数のデータをCString Text1という変数に 以下のようなソースで文字列連結処理を行ったのですが、だめでした。 何がいけないのでしょうか? for(int i = 0; i <= 2; i++) { Text1 += Test[i]; } 実行結果は Text1には"2"が格納されたままでした。 実際はText1には、"2""1"となってほしい。 分かりにくい説明とは思いますが、 回答、ヒントなどを頂けますでしょうか 宜しくお願い致します。 それと、もしよかったら、Text1の格納データは "2","1"としたいので、カンマ区切りのやりかたなども ヒントを頂けたら幸いです。 以上です。 宜しくお願い致します。

  • perl:ループのカウンタ変数の値を保持したい。

    While文のループのなかにfor文でループをまわしているスクリプトなのですが、 forの中でカウンタ変数をつくり、ループ回数を計測しております。 またforの中である条件を満たした際に、lastでforを抜け、引き続きWhileのループを継続するという処理をしております。 $i=0; While(○○){ 処理1    for(××){ 処理2 $i++;      if($i >=100){  処理3       last; } } } ここで、一度for文のif文で一度forループを抜け、Whileでループをし、またforループに突入した際に、前回forループでカウントした$iの値を保持したまま、そのつづきから$iのカウンタを動作させたいのですが、$iの値はforループを抜けるとリセットしてしまいます。 このような場合、どうすれば$iの値を保持できますでしょうか。 お詳しい方、宜しくお願い致します。 ※ネストがうまく表現できず、みずらくてスミマセン。

    • ベストアンサー
    • Perl
  • VBAにおけるRank関数について

    たびたびの質問で申し訳ないです。VBAで、sheet"C"のC列に得点のデータがあって、D列に順位を付けていきたいのですが、うまくできません。↓のように書いたら、構文エラーが出てしまいます。どうかご回答よろしくお願いします。 For i = 2 To 43 Worksheets("C").Range ("Di").Value = Application.WorksheetFunction.Rank(Worksheets("C").Range ("Ci").Value. Worksheets("C").Range("B2:B43").0) Next i

  • Perlの初歩的な質問・・・

    @data に大量のデータが格納されていると仮定して、次のようにループ処理するとします・・・ for($i = 0 ; $i < @data ; ++$i){ @XXX = split(/\t/, $data[$i]); } このように @data のデータをさらに細かく配列化して @XXX に代入したいのですが、ループのたびに @XXX の名前を XXX0 , XXX1 , XXX2..... とするには、どうしたらよいのでしょうか。

    • ベストアンサー
    • Perl
  • エクセル【RANK関数の入力について】

    http://www.eurus.dti.ne.jp/~yoneyama/Excel/nyumon/seiseki/sei-n05.htm 上記のサイトでエクセルを勉強中の者です。 『(練習1)RANK関数の入力』の5で『I5セルのフィルハンドルをドラッグして、I14セルまで数式をコピーします。』となっているのですが、私がやった場合、図の通りの数字の順位になりません。 I5は範囲がH5~H14の場合の順位なので9位となるのですが、それ以降は範囲がそれぞれ1ずつ下がった状態で計算しているみたいで、I6は範囲がH6~H15になってしまい、本来5位のはずが6位となってしまいます。 多分何かがおかしいと思うのですが、宜しければご教授お願い致します。