HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2007
0317
ひーよーこー配列変数の最大値5解決


ひーよーこー

リンク

2007/3/17(Sat) 21:33:42|NO.6395

数字型の配列変数の最大値の楽な求め方を知りたいです。
それともひとつずつ地道に比べて割り出すしかありませんか?
返答よろしくお願いします。



この記事に返信する


a

リンク

2007/3/18(Sun) 03:30:46|NO.6401

楽な求め方だってよw今やってることが既に楽してるよなw



ccc

リンク

2007/3/18(Sun) 03:35:49|NO.6402

おっと悪い悪い不完全なまま投稿されてしまったようだw
トランプカードの束を想像してみろw数字の大小がばらばらのまま束にした中からキングを探すのは一枚づつ調べなきゃできないだろ。じゃぁキングを効率よく探すにはどうすりゃいい?束にするときにキングを一番上にもってくりゃいいんだよw

イマジネーション膨らませてコードかけよ。プログラミングに正解なんてねぇっつーのw



93

リンク

2007/3/18(Sun) 12:27:21|NO.6405

ソートでよければコムソート11というのを利用してみるのはどうでしょうか?
小さい=先頭、大きい=末尾を取得すればよいかもしれません。

#module // // コムソート11(高速なソートでつ) // // p1 = 配列変数 #deffunc CombSort11 array p1 /*変数初期化*/ : max = length(p1) : gap = length(p1) repeat : gap = (gap*10)/13 if (gap == 9)|(gap == 10) { : gap = 11 } if (gap < 1) { : gap = 1 } : swaped = 0 : i = 0 repeat if (i < max-gap) { : k = i+gap if (p1(i) > p1(k)) { : dummy = p1(i) : p1(i) = p1(k) : p1(k) = dummy : swaped = 1 } : i++ } else { break } loop if (gap <= 1)&(swaped != 0) { break } loop return #global title "コムソート11" /*用意*/ sdim buf, 1024, 2 pos 0, 0 : mes "前" pos 0, 20 : mesbox buf(0), ginfo(12), ginfo(13)/3 pos 0, 20+(ginfo(13)/3)*1 : mes "後" pos 0, 40+(ginfo(13)/3)*1 : mesbox buf(1), ginfo(12), ginfo(13)/3 randomize repeat 1024 DATE(cnt) = rnd(9000) buf(0) = buf(0)+DATE(cnt)+"\n" loop objprm 0, buf(0) /*ここだけ*/ CombSort11 DATE repeat 1024 buf(1) = buf(1)+DATE(cnt)+"\n" loop objprm 1, buf(1)



Drip

リンク

2007/3/18(Sun) 13:57:38|NO.6407

Dripです。

 ひーよーこーさん、こんにちは。
恐らくひーよーこーさんが考えているのは、楽な最大値取得というより
高速な最大値の取得方法だと思います。
数十個の配列であればrepeat-loopでひとつずつ比較していく方法で問題ないと思いますが、
大量の配列を持つ変数だった場合、特にゲームプログラム等でリアルタイム処理が
要求される場合は、最大値ひとつ求めるのにかなりの処理時間がかかってしまい、
問題がありますね。

 高速に最大値を求める手段は2つほど思いつきます。
まず1つ目はhspda.dllというHSP3に標準装備されたプラグインを使うことです。
以下にhspda.dllを使用した簡単な最大値取得のサンプルを示します。

#include "hspda.as" randomize:pos 10,10 repeat 20:x(cnt)=rnd(100):mes ""+cnt+": "+x(cnt):loop sortval x,1:sortget t,0 //ソートして最大値と元のIndex取得 pos 200,50:mes "最大値:配列 "+t+" の "+x(0)+" が最大" //但し、この方法ではデータが全てソートされてしまいます!
 こちらの環境ではこの方法で一千万件のデータを1.579秒で処理し、最大値を
取得できました。しかし、見てわかる通り、途中でソート処理が挟まれているため、
無駄な処理が多すぎることも確かです。

 更に高速に最大値を求める手段の一つとしてネイティブコードを扱う方法が考えられます。
こちらはC言語がわからないとサンプルを理解するのは難しいですが、試しに下のコードを
実行してみて下さい。

#module #uselib "kernel32.dll" #func VP "VirtualProtect" var,int,int,var #defcfunc maxget array ary if mc=0:{VP mc,44,$40,NL mc.0=$53ec8b55,$08458b56,$088bf633,$553bd233,$8b137d0c mc.5=$7dcb3b18,$8bcb8b04,$c08342f2,$0c553b04,$c68bed7c mc.10=$c35d5b5e:mcp=varptr(mc) }:prm=varptr(ary),length(ary):return callfunc(prm,mcp,2) #global randomize:pos 10,10 repeat 20:x(cnt)=rnd(100):mes ""+cnt+": "+x(cnt):loop t=maxget(x) pos 200,50:mes "最大値:配列 "+t+" の "+x(t)+" が最大"

 こちらの環境では、このmaxget関数を利用した場合、
一千万件のデータを約0.03秒で処理し、最大値を取得することができました。
これならば一般的なゲームアプリケーションでフレーム毎の使用にも耐えることができます。

 私が上げたサンプルは、あまりに配列数が多すぎてとてもHSPで処理するには重過ぎる、
という場合に使用される方法ですので、通常はrepeat-loopで最大値を一件一件検索して
行く方法で十分です。
用途に合わせ、最大値の取得方法を考えてみてください。



ひーよーこー

リンク

2007/3/18(Sun) 17:22:10|NO.6411

93さん、Dripさん
返答ありがとうございます。
今は時間がないので今度試してみようと思います。
ありがとうございました。



ONION software Copyright 1997-2021(c) All rights reserved.