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

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

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

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ソート

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

Q&A

1回答

1213閲覧

マージソートでソート済みの数値が出力されない。(VBA)

whitehorse85921

総合スコア34

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マージ

複数のデータベースやファイル、プログラムなどを決まった手順や規則に従って一つに結合すること。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

ソート

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

0グッド

0クリップ

投稿2021/01/24 10:13

前提・実現したいこと

マージソートでソート済みの数値を出力したいです。

発生している問題・エラーメッセージ

エラーはございません。

該当のソースコード

VBA

1Option Explicit 2 3Dim A() As Variant '配列Aをグローバル変数にしました 4Dim n As Long 'n個の配列Aを作る 5Dim L() As Variant 6Dim R() As Variant 7Dim cnt As Long 'ファンクションmergeにおける比較回数の総数 8 9'得られた2つのソート済み部分配列をmergeにより「統合」 10Function merge(A() As Variant, n As Long, left As Long, mid As Long, right As Long) 11 Dim n1 As Long 12 Dim n2 As Long 13 Dim i As Long 14 Dim j As Long 15 Dim k As Long 16 17 n1 = mid - left 18 n2 = right - mid 19 20 ReDim L(mid - left) 21 ReDim R(right - mid) 22 23 For i = 0 To n1 - 1 24 L(i) = A(left + i) 25 Next i 26 For i = 0 To n2 - 1 27 R(i) = A(mid + i) 28 Next i 29 30 i = 0 31 j = 0 32 For k = left To right - 1 33 cnt = cnt + 1 34 If L(i) <= R(i) Then 35 A(k) = L(i + 1) 36 Else 37 A(k) = R(j + 1) 38 End If 39 Next k 40 Erase L 41 Erase R 42End Function 43 44 45'指定されたn個の要素を含む部分配列をそれぞれn/2の要素を含む2つの部分配列に分割する 46'その2つの部分配列をそれぞれmergeSortでソートする 47Function mergeSort(A() As Variant, n As Long, left As Long, right As Long) 48 If (left + 1) < right Then 49 Dim mid As Long 50 mid = (left + right) / 2 51 Call mergeSort(A, n, left, mid) 52 Call mergeSort(A, n, mid, right) 53 Call merge(A, n, left, mid, right) 54 End If 55End Function 56 57Sub main() 58 Dim i As Long 59 60 cnt = 0 61 62 A = Array(8, 5, 9, 2, 6, 3, 7, 1, 10, 4) 63 64 n = UBound(A) + 1 65 66 Call mergeSort(A, n, 0, n) 67 68 For i = 0 To UBound(A) 69 Debug.Print A(i) 70 Next 71 72 Debug.Print cnt 73End Sub

試したこと

ヴァリアント型の配列Aをグローバル変数にしました。そうすることでmergeSortでソートされた配列AがDebug.Printで表示されると思ったのですが上手くいきませんでした。

補足情報(FW/ツールのバージョンなど)

変数cntはmergeファンクションにおける比較回数の総数を表しています。
Microsoft Excel 2016

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

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

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

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

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

episteme

2021/01/24 10:59

> 上手くいきませんでした なにが/どのように"上手くいきませんでした"なのか、説明してください。
whitehorse85921

2021/01/24 11:17

epsteme様 ありがとうございます。 配列変数Aをグローバル変数にすれば変数の適用範囲が広がりファンクションmergeSortやファンクションmergeでの配列変数Aの処理をmainに渡せると思いました。でもmergeにおけるっ比較回数は上手く表示されるのですが、「ファンクションmergeSortでソートされた数値」が全く表示されませんでした。
episteme

2021/01/24 12:49

> 配列変数Aをグローバル変数にすれば変数の適用範囲が広がりファンクションmergeSortやファンクションmergeでの配列変数Aの処理をmainに渡せると思いました。 そのアイデアが正しいか、確認しましたか?
whitehorse85921

2021/01/24 16:02

episteme様 ありがとうございます。 デバッグするとファンクションmergeの For k = left To right - 1 cnt = cnt + 1 If L(i) <= R(i) Then A(k) = L(i + 1) Else A(k) = R(j + 1) End If Next k のところで A(k) = L(i + 1)もA(k) = R(j + 1)も共にempty値になってしまいます。
guest

回答1

0

mergeの処理が間違っているのでL,Rにそれぞれどんな値が入ってAがどう変化していくべきか
要素数少なめの配列で1行1行処理を追ってください。

特にkのループ周辺がおかしく
L,Rの添え字に使っているi,jが一切加算されていないので、
If L(i) <= R(i) は常に同じ結果となります。
そのため、A(k)には同じ値が入り続けます。
A(k)に代入したL,Rは再代入しないようi,jを加算する。

If L(i) <= R(i) ThenとなっていますがR(j)だと思います。

i,jを加算するとインデックスが有効範囲ではありません等のエラーが出ると思いますが、
回避方法が様々なので考えてみてください。

投稿2021/01/26 12:58

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

whitehorse85921

2021/02/26 19:39

SoshiAdachiさんお返事遅れてしまい大変申し訳ありません。 このコードは元はC++のコードです。またご指摘いただいた通り、R(i)ではなくR(j)でした。自分ではお手上げですが、ご回答いただいたこと誠にありがとございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問