質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

Emacs

GNU Emacsと拡張性の高い、高性能なテキストエディタです。豊富なライブラリの導入により、統合開発環境やWebブラウザとしても機能させる事が可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

3回答

2859閲覧

メジアンについて

peke

総合スコア13

Cygwin

Cygwinは、Unixのような環境を、Windows上で構築させるコマンドラインインターフェースです。

Emacs

GNU Emacsと拡張性の高い、高性能なテキストエディタです。豊富なライブラリの導入により、統合開発環境やWebブラウザとしても機能させる事が可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2016/06/11 08:04

編集2016/06/11 10:20

学校で出されたプログラミングの問題を解いていたのですが
実行はできるのですがうまく答えが一致しません。

Main ######から後ろは問題の条件の部分をコピペしたのでおそらくあっているはずなので

それより上の部分でどこが違うのでしょうか。
ご指摘よろしくおねがいします。

【問題】
複数の数値データを配列で与えると, メジアンを計算して,その値を戻り値として返す メソッドを作りたい
このメソッドの内容は次のようなものである.
メソッド名は median とする.
データの配列を仮引数として受取る.
配列のデータはすでに昇順でソートされている.
データ数が奇数の場合には,中央の値をメジアンとして返す.
データ数が偶数の場合には,中央の2つの値の平均をメジアンとして返す.
【私の解答】
def median(data)
n = 0
m = 0
l = data.size - 1
if data.size % 2 == 1 then
n = data[(data.size) / 2]
return n
else data.size % 2 == 0
m = (data[1/2] + data[1/2 + 1]) /2
return m
end
end
####### Main #######
ar1 = [30.9,31.8,32.0,32.7,32.8,33.1,34.2,35.3,36.2,39.1,39.2,39.8]
ar2 = [31.0,31.3,31.7,31.7,32.3,33.8,34.0,35.2,35.2,38.8,38.8,39.6,39.7]
puts "メジアンは #{median(ar1)}です。"
puts "メジアンは #{median(ar2)}です。"

実行結果
正しい結果
メジアンは 34.25です。
メジアンは 35.5です。
私の結果
メジアンは 30.65です。
メジアンは 35.5です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

eripong

2016/06/11 10:17

このまま実行すると、メジアンは 31.35です。メジアンは 34.0です。となって質問文の「私の実行結果」と結果が違うのですが、ar1やar2は正しいですか?
peke

2016/06/11 10:21

ar1やar2は先生の提示したものをコピペしたものなので正しいはずなのですが...
eripong

2016/06/11 10:24

pekeさんの質問にあるコードをpaiza.ioで実行して違う結果なので、「私の実行結果」かar1、ar2のどちらかが違うのではと思うのですが。。
guest

回答3

0

ベストアンサー

プログラムをすこし変更してみました。
a.rb

ruby

1def median(data) 2 len = data.size 3 if len % 2 == 1 4 return data[(len) / 2] 5 else 6 return (data[len / 2 - 1] + data[len / 2]) / 2 7 end 8end 9 10# Main ####### 11ar1 = [ 12 30.9, 31.8, 32.0, 32.7, 32.8, 33.1, 13 34.2, 35.3, 36.2, 39.1, 39.2, 39.8 14] 15ar2 = [ 16 31.0, 31.3, 31.7, 31.7, 32.3, 33.8, 34.0, 17 35.2, 35.2, 38.8, 38.8, 39.6, 39.7] 18puts "メジアンは #{median(ar1)} です。" 19puts "メジアンは #{median(ar2)} です。"

実行結果

$ ruby a.rb メジアンは 33.650000000000006 です。 メジアンは 34.0 です。

ar1 のデータ内容は、課題のものと合っていますか?
再確認をお願いします。

質問文では、ar1 の median のプログラムでの計算結果が 30.35 となっています。
でも ar1 は 30.9 から始まっているので、 計算結果は 30.9 より大きな数となるはずなのですが ....

投稿2016/06/11 11:03

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

peke

2016/06/11 11:12

ありがとうございます!! できました!!
退会済みユーザー

退会済みユーザー

2016/06/11 11:22

すみません。非常に個人的な興味です。 #{median(ar1)} は(33.1+34.2)/2 だと思うのですが、こんなに誤差がでるものですか?割り切れないものでも無いので、非常に不思議です。
katoy

2016/06/11 11:51

$ irb irb(main):001:0> (33.1 + 34.2) / 2 => 33.650000000000006 コンピュータ内部では2進数で計算します。 10進数との変換や、内部でも計算処理によって誤差が発生します。 "計算誤差" で google 検索してみると、いろいろ情報が得られます。
退会済みユーザー

退会済みユーザー

2016/06/11 12:12

rubyだとそうなるんですかねぇ。。。 ちょっとおもしろそうなので、検証して、別の質問として立ててみます。 ありがとうございました。
katoy

2016/06/11 12:17

c でも、 java でも、計算誤差は発生します。 典型的な例として、 大抵の言語では普通は 1 / 3 * 3 は 1 にはなりません。 0.9999... となってしまいます。
guest

0

正しい結果と言っているものは正しいですか?
計算していませんが、
・データ数が奇数の場合には,中央の値をメジアンとして返す.
・データ数が偶数の場合には,中央の2つの値の平均をメジアンとして返す.
とあるので、
・奇数の場合、配列の中の数字のいずれか
・偶数の場合、中央の2つの値の平均であるため、小数点以下は2桁までで、かつ2桁目は0or5
となるはずです。

投稿2016/06/11 09:59

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

peke

2016/06/11 10:21

正しい結果は私のミスで違っていたようです。 訂正させてもらいました。
退会済みユーザー

退会済みユーザー

2016/06/11 10:30

Ruby は使わないのでこれ以上のことは分かりませんが、これとは別に配列をソートする部分がありますよね?そちらも掲載されては?
退会済みユーザー

退会済みユーザー

2016/06/11 11:18

失礼。ソートはされてますね^^; となると、問題文の定義から、答えは ar1:(33.1+34.2)/2 = 33.65 ar2: 34.0 やっぱり、正解が違うようです。 また、ソースの正当性の確認は、 data[(data.size) / 2] data[1/2] data[1/2 + 1] が意図した数字になっているか確認すれば、すぐに分かります。 出力してみては?
guest

0

推測で申し訳ないのですが、丸め誤差が起きているのかと思います。
解決方法は様々な種類がありますので、webで[ruby 丸め誤差]と検索してみるといいかもしれないです。

投稿2016/06/11 09:38

編集2016/06/11 09:44
774

総合スコア79

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

peke

2016/06/11 10:13

丸め誤差とは切り捨て切り上げのことであっていますよね? 5も誤差は起きるものなんでしょうか...
774

2016/06/11 11:02

申し訳ない、正しいパターンと間違っているパターンを見てそう書きました。混乱させてしまい申し訳ありません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問