スクリプト/汎用関数/配列をソートする

最終投稿者:Cdv30200 aoi icon mini aoihikawa 更新:2017/04/05 22:35:25
配列をソートする
(ご自由にご利用ください)

#配列ソート
def pivot(arr,i,j,ord)
  k = i + 1
  while (k <= j) && (arr[i] == arr[k]) do k = k + 1; end
  if k > j then return -1; end
  if ord
    if arr[i] >= arr[k] then return i; end
  else
    if arr[i] <= arr[k] then return i; end
  end
  return k
end

def partition(arr,i,j,x,ord)
  l = i; r = j
  while l <= r
    if ord
      while (l <= j) && (arr[l] < x) do l = l + 1; end
      while (r >= i) && (arr[r] >= x) do r = r - 1; end
    else
      while (l <= j) && (arr[l] > x) do l = l + 1; end
      while (r >= i) && (arr[r] <= x) do r = r - 1; end
    end
    if l <= r
      t = arr[l]; arr[l] = arr[r]; arr[r] = t
      l = l + 1; r = r - 1
    end
  end
  return l
end

def quickSort(arr,i,j,ord)
  if i != j
    p = pivot(arr,i,j,ord)
    if p != -1
      k = partition(arr,i,j,arr[p],ord)
      arr = quickSort(arr,i,(k - 1),ord)
      arr = quickSort(arr,k,j,ord)
    end
  end
  return arr
end

#使用時はこの関数のみ
#第1引数:配列 第2引数:昇順 true / 降順 false
def sortArray(arr,ord)
  return quickSort(arr,0,(getArrayLength(arr) - 1),ord)
end


 使用例
aList = createArray()
aList[0] = 3 
aList[1] = 1 
aList[2] = 4
aList[3] = 6
aList[4] = 2
aList[5] = 8
aList[6] = 7
aList[7] = 5
aList[8] = 9
aList[9] = 3

#配列を降順に並べ替え
aList = sortArray(aList, false)
speak(aList) #9,8,7,6,5,4,3,3,2,1


bList = createArray()
bList[0] = "すみれ"
bList[1] = "ひまわり"
bList[2] = "あかね"
bList[3] = "なずな"
bList[4] = "あおい"
bList[5] = "われもこう"
bList[6] = "ききょう"
bList[7] = "れんげ"
bList[8] = "すずらん"
bList[9] = "あんず"

#配列を昇順に並べ替え
bList = sortArray(bList, true)
speak(bList) #あおい,あかね,あんず,ききょう,すずらん,すみれ,なずな,ひまわり,れんげ,われもこう


参考文献:クイックソート

ご意見やご質問などありましたら
こちらのブログ記事まで。

コメントする

コメントするには、ログインする必要があります。

コメント一覧

            mini mosmoss(投稿日:2017/04/05 19:20, 履歴)
この関数とても助かってるんですが、
配列を二次元配列aにして、a[i][0]に数値を入れて並び替えるような時、
数値の桁が違うと数値が順番にならないようです

aa=createArray()
a=createArray()
a[0]=88
a[1]=0
pushArray(aa, a)
a=createArray()
a[0]=89
a[1]=1
pushArray(aa, a)
a=createArray()
a[0]=109
a[1]=2
pushArray(aa, a)
a=createArray()
a[0]=60
a[1]=3
pushArray(aa, a)
a=createArray()
a[0]=960
a[1]=4
pushArray(aa, a)

speak(aa[0][0], aa[1][0], aa[2][0], aa[3][0], aa[4][0])
#88,89,109,60,960
aa=sortArray(aa,false)
speak(aa[0][0], aa[1][0], aa[2][0], aa[3][0], aa[4][0])
#960,89,88,60,109 #二次元配列だと数値の比較での降順にならず、文字列比較になる?ため、109が一番下に来てしまう

a=createArray()
a[0]=88; a[1]=89; a[2]=109; a[3]=60; a[4]=960
speak(a[0], a[1], a[2], a[3], a[4])
#88,89,109,60,960
a=sortArray(a,false)
speak(a[0], a[1], a[2], a[3], a[4])
#960,109,89,88,60 #一次元配列なら数値の比較で降順になる

このように、一次元配列でない時、文字列的な比較での並び替えになるようです

配列a[i][0]にスコア、a[i][1]にプレイヤー名などを入れて、
a[i][0]のスコアを並び替えてランキングを作る・・・みたいなことをしたかったので、
100以下の数値の時に、数値の前に" "を足して使ってます。
しかし、原因がよくわからないため、報告しました。
Cdv30200 aoi icon mini aoihikawa(投稿日:2017/04/05 20:58, 履歴)
多次元配列をソートした場合、
今回の例でいくと、
「88,0」「89,1」「109,2」「60,3」「960,4」という『,』を含んだ値=文字列のソート判定となり、
想定された動作にならないことを確認いたしました
            mini mosmoss(投稿日:2017/04/05 21:25, 履歴)
ありがとうございます!
きれいな関数なので自分では理由がわかりませんでした。
理由がわかったことでより使いやすくなりました。
Cdv30200 aoi icon mini aoihikawa(投稿日:2017/04/05 21:46, 履歴)
def pivot2(arr,index,i,j,ord)
  k = i + 1
  while (k <= j) && (arr[i][index] == arr[k][index]) do k = k + 1; end
  if k > j then return -1; end
  if ord
    if arr[i][index] >= arr[k][index] then return i; end
  else
    if arr[i][index] <= arr[k][index] then return i; end
  end
  return k
end

def partition2(arr,index,i,j,x,ord)
  l = i; r = j
  while l <= r
    if ord
      while (l <= j) && (arr[l][index] < x) do l = l + 1; end
      while (r >= i) && (arr[r][index] >= x) do r = r - 1; end
    else
      while (l <= j) && (arr[l][index] > x) do l = l + 1; end
      while (r >= i) && (arr[r][index] <= x) do r = r - 1; end
    end
    if l <= r
      t = arr[l]; arr[l] = arr[r]; arr[r] = t
      l = l + 1; r = r - 1
    end
  end
  return l
end

def quickSort2(arr,index,i,j,ord)
  if i != j
    p = pivot2(arr,index,i,j,ord)
    if p != -1
      k = partition2(arr,index,i,j,arr[p][index],ord)
      arr = quickSort2(arr,index,i,(k - 1),ord)
      arr = quickSort2(arr,index,k,j,ord)
    end
  end
  return arr
end


#使用時はこの関数のみ
#第1引数:配列 第2引数:ソート対象のインデックス 第3引数:昇順 true / 降順 false
def sortArray2(arr,index,ord)
  return quickSort2(arr,index,0,(getArrayLength(arr) - 1),ord)
end


多次元配列用のソート関数を用意しました
こちらをご利用頂けましたら幸いです


<サンプル>
#配列内、0番目の配列データをソート対象にする
aa=sortArray2(aa,0,false)
speak(aa[0][0], aa[1][0], aa[2][0], aa[3][0], aa[4][0])
            mini mosmoss(投稿日:2017/04/05 22:35, 履歴)
ありがとうございます!