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

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

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

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1120閲覧

配列をソートした 27 ときのそのデータの位置とlstの中の位置のズレの総和を計算する

Q3fdxrGzWzu0u5n

総合スコア8

ソート

複数のデータを、順序性に従って並べ替えること。 データ処理を行う際に頻繁に用いられ、多くのアルゴリズムが存在します。速度、容量、複雑さなどに違いがあり、高速性に特化したものにクイックソートがあります。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/07/17 09:28

数を要素とする配列 lst が与えられたとき,その配列をソートしたときのそのデータの位置とlstの中の位置のズレの総和を計算する関数 f(lst)を作りたいです.現状のプログラムでは,ただクイックソートを行うだけなので,ズレの総和を計算するにはどうすれば良いでしょうか?

Javascript

1function f(lst){ 2 function quicksort(a, l, r){ 3 var v, i, j 4 if (r > l){ 5 v = a[r]; 6 [i, j] = [l - 1, r] 7 while (true){ 8 i += 1; while (a[i] < v) i += 1 9 j -= 1; while (a[j] > v) j -= 1 10 if (j <= i) break; 11 [a[i], a[j]] = [a[j], a[i]] 12 } 13 [a[i], a[r]] = [a[r], a[i]] 14 quicksort(a, l, i - 1) 15 quicksort(a, i + 1, r) 16 } 17 } 18 var count = 0 19 var a = lst 20 quicksort(a, 0, a.length -1) 21 puts(count) 22 return a 23} 24var lst = [ 1,2, 3, 6, 8] 25puts(f(lst))

実際に求めたい出力結果の例が以下のとおりです.
f([4,3,2,1]) = 8
f([2,3,2,1]) = 6
f([1,2,3,6,8]) = 0
f([9,1,2,3,6]) = 8
f([1,1,1,1,1]) = 0

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

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

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

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

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

yambejp

2020/07/17 10:05

f([2,3,2,1]) = 6 f([9,1,2,3,6]) = 8 の根拠がよくわかりません。 ズレの総和とはどういうロジックなのでしょうか?
Q3fdxrGzWzu0u5n

2020/07/17 10:12

例えば,lst = [4,3,2,1]でしたら,4を右に3,3を右に1,2を左に1,1を右に3動かすため,それぞれ足して,8となります.
guest

回答2

0

ベストアンサー

こんにちは

一案としまして、以下のような感じになるかと思います。

javascript

1const f = (lst) => { 2 3 const lstSorted = [...lst].sort((v1, v2) => v1 - v2); 4 5 const sum = lst.reduce((s, v, i) => { 6 const j = lstSorted.indexOf(v); 7 lstSorted[j] = NaN; 8 return s + Math.abs(i - j); 9 }, 0); 10 11 return sum; 12};

追記1

上記の回答コードでは、引数で与えられた lst(のコピー)をソートした lstSorted を得るために javascript標準の sort メソッドを使って

javascript

1const lstSorted = [...lst].sort((v1, v2) => v1 - v2);

としていますが、Q3fdxrGzWzu0u5nさんが自作されたquicksortを使えば、以下の二行

javascript

1const lstSorted = [...lst]; 2quicksort(lstSorted, 0, lstSorted.length -1)

によっても得られます。

追記2

別案を挙げます。

与えられた配列 lst が例えば [40, 30, 20, 10] だった場合に、この配列のコピーをソートするのではなく、lst の要素とインデクスを並べた、長さ2の配列を要素とする配列

[ [40, 0], [30, 1], [20, 2], [10, 3] ]

を作り、この配列を各要素の先頭の値で昇順ソートすると以下が得られます。

[ [10, 3], [20, 2], [30, 1], [40, 0] ]

上記の配列を使うと、各要素の移動量の計算は、各要素の配列の二番目に入っているソート前のインデクスと、ソート後の配列の各要素それ自体のインデクスの差から求めることができます。以下はこの考え方による f(lst) です。

javascript

1const f = lst => 2 lst.map((v, i) => [v, i]) 3 .sort(([v1],[v2]) => v1 - v2) 4 .reduce((s, [v, i], j) => s + Math.abs(i-j), 0);

投稿2020/07/17 10:26

編集2020/07/17 19:00
jun68ykt

総合スコア9058

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

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

0

ソート前の配列からソート後の配列を引いて絶対値を足して行けば良いのでは?
ただし、単に配列を新しい変数に代入しただけだと、2つの変数の中身が同じものになってしまうのでコピーする必要があります。

var s=0; var a=lst.concat(); //値をコピー quicksort(a, 0, a.length -1) for(var i =0;i<lst.length;i++) s+=Math.abs(lst[i]-a[i]); console.log(s);

投稿2020/07/17 10:12

Kaleidoscope

総合スコア257

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問