-
Notifications
You must be signed in to change notification settings - Fork 0
/
02_myarray_srch.hsp
770 lines (611 loc) · 23.4 KB
/
02_myarray_srch.hsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
; INFO *************************************************************************
; FileName : 02_myarray_srch.hsp
; Version : 0.28.3
; Date : 2023/04/01
; Author : YUZRANIUM(ゆずらにうむ)
; Twitter : https://twitter.com/YUZRANIUM
; GitHub : https://github.com/YUZRANIUM/02_myarray
;*******************************************************************************
/* Description
このモジュールはソートや線形探索・二分木探索など、ユーザーに提供する一部機能の
前処理を行う、local指定を含む7つの命令・関数郡からなるモジュールです。
元々、内部命令・関数だったものですがあると便利なものかなと思い、
改良して公開することになったものです。
*** スコープ情報 ***
- 輸入品 -
myarray_core から
* dim_info (MDALiSrch_, MDABiSrch_)
* TypeCnv (MDALiSrch_, MDABiSrch_)
myarray_list から
* uniary_ (MDALiSrch_, MDABiSrch_)
- 輸出品 -
myarray へ
* LiSrchc_ (_myarray_init_)
* twinsortary (_myarray_init_)
* bisrch_ (mlgetc)
********************************************************************************/
#ifndef __myarray_srch__
#define global __myarray_srch__
; このモジュールは myarrayモジュール内で使用していた命令・関数の中でも
; 特に汎用性が高く、補助的なものを集めて分離させたものです。
;
#module "myarray_srch"
; myarray_srchモジュールの内部変数の初期化
; このファイルの最下部で呼び出しておりますので、特別呼び出す必要はありません。
;
#deffunc local _myarray_srch_init_
midlevar_ = ""
dim _my_tmp_ ; twinsortary命令 一時保存用
dim sortgetc_res_ ; sortgetc関数 返り値用変数
dim found_ ; LiSrchc_関数 返り値用変数
dim item_asci ; 検索文字列のASCIIコード
dim asci_ary ; 比較サンプル用のASCIIコード
dim srch_ary_inf_, 8 ; MDALiSrch関数 配列情報用
dim srch_ary_var_, 3 ; MDALiSrch関数 型変換用
dim prm_chk, 2 ; MDALiSrch関数 条件式用
dim i, 9 ; MDALiSrch関数 多目的
; i(0), i(1), i(2), i(3), i(5), i(6) : 6分割で探索するための要素数用
; i(7) : 戻り値用変数
; i(8) : 発見フラグ
dim pvt, 3 ; ピボット候補の格納用
; ピボット候補用ASCIIコード
dim pvt0 : dim pvt1 : dim pvt2
dim pivotasc
dim frst_asc
dim last_asc
return
;-------------------------------------------------------------------------------
;
; 文字列からASCIIコードに変換
;
; str2ASCII_ ary1, s1
;
; [array] ary1 : ASCIIコードを受け取る変数名
; [ str ] s1 : 変換したい文字列
;
#deffunc str2ASCI array ary1, str s1
; バイト数を得るために変数に代入
midlevar_ = s1 : notesel midlevar_
dim ary1, notesize
; 文字列をASCIIコードに
repeat notesize: ary1(cnt) = peek(midlevar_, cnt) :loop
ary1(notesize) = 0 ; 終了コード
return
;-------------------------------------------------------------------------------
;
; ASCIIコードから文字列に変換
;
; val = ASCII2str_(ary1)
;
; [array] ary1 : ASCIIコードを格納した変数名
;
; *** 返り値 ***
; refstr : 復元した文字列
;
#defcfunc ASCI2str array ary1, local hoge_
sdim midlevar_, 64
repeat length(ary1)
getstr hoge_, ary1(cnt), 0
midlevar_ += hoge_
loop
return midlevar_
;-------------------------------------------------------------------------------
;
; 大小比較
;
; val = ASCIcomp(ary1, ary2, p1)
;
; [array] ary1,ary2 : ASCIIコードを格納した変数名
; [ int ] p1 : 返りフラグ (= 0, 0:小さい方 / 1:大きい方)
;
; *** 返り値 ***
; stat : 比較結果
; : 0:完全一致
; : 1:第一パラメータ
; : 2:第二パラメータ
;
#defcfunc ASCIcomp array ary1, array ary2, int p1
; 大小ポイント
dim ary1_pt, 2
dim ary2_pt, 2
dim i
; 比較回数は小さい方に合わせる 文字数の大きい方に1pt
if (length(ary1) < length(ary2)) {i = length(ary1) : ary2_pt(1)++}
else:if (length(ary1) > length(ary2)) {i = length(ary2) : ary1_pt(1)++}
else {i = length(ary1)}
; 大きい方に1pt入る. 同じ場合はpt入れないで次の文字コード比較へ
repeat i
if (ary1(cnt) < ary2(cnt)) {ary2_pt++ : break}
else:if (ary1(cnt) > ary2(cnt)) {ary1_pt++ : break}
loop
; p1 = 0 のときは小さい方を, p1 = 1 のときは大きい方を返す
if (ary1_pt(0) < ary2_pt(0)) & p1 {return 2} ; 第2パラメータの文字列が大きい
else:if (ary1_pt(0) > ary2_pt(0)) & p1 {return 1} ; 第1パラメータの文字列が大きい
else:if (ary1_pt(1) < ary2_pt(1)) & p1 {return 2} ; 文字数の長いほうが大きい
else:if (ary1_pt(1) > ary2_pt(1)) & p1 {return 1} ;
else:if (ary1_pt(0) < ary2_pt(0)) {return 1}
else:if (ary1_pt(0) > ary2_pt(0)) {return 2}
else:if (ary1_pt(1) < ary2_pt(1)) {return 1}
else:if (ary1_pt(1) > ary2_pt(1)) {return 2} else {return 0}
;-------------------------------------------------------------------------------
;
; sortgetの関数バージョン
;
; sortgetc index
;
; [ int ] index : インデックス
;
; *** 返り値 ***
; stat : 1次元配列の要素数
;
#defcfunc sortgetc int index
sortget sortgetc_res_, index
return sortgetc_res_
;-------------------------------------------------------------------------------
;
; 一方の配列のソートに合わせて他方もソート
;
; twinsortary ary1, ary2, p1
;
; [array] ary1 : メインでソートする配列変数名
; [array] ary2 : 配列変数名 (ary1に合わせてソート)
; [ int ] p1 : 昇降順
;
#deffunc twinsortary array ary1, array ary2, int p1
; 一時保存
dimtype _my_tmp_, vartype(ary2), length(ary2)
foreach ary2: _my_tmp_(cnt) = ary2(cnt) :loop
; 変数型に合わせて分岐・メインの配列ソート実行
if (vartype(ary1) = 4) {sortval ary1, p1}
else:if (vartype(ary1) = 2) {sortstr ary1, p1}
foreach ary2: ary2(cnt) = _my_tmp_(sortgetc(cnt)) :loop
return
;-------------------------------------------------------------------------------
;
; 文字列リストとの線形探索
;
; val = LiSrchc_(item_, srch_ary)
;
; [ var ] item_ : 探索値
; [array] srch_ary : 変数名 (探索場所)
;
; *** 返り値 ***
; stat : 1次元配列の要素
;
#defcfunc local LiSrchc_ var item_, array srch_ary
found_ = 0
repeat length(srch_ary)
if (instr(item_, 0, srch_ary.cnt) != -1) {found_ = 1 : break}
loop
return found_
;-------------------------------------------------------------------------------
;
; リストとの線形探索 (多次元配列仕様) (由来 : Multi Dimensional Array Line Search)
;
; MDALiSrch item_, srch_ary
;
; [ str ] item_ : 探索値
; [array] srch_ary : 変数名 (探索場所)
;
; *** 戻り値 ***
; stat : 配列のオフセット値 (1次元化要素数)
;
#defcfunc local MDALiSrch_ str item_, array srch_ary
; 配列情報の取得
dim srch_ary_inf_, 7
dim_info srch_ary, srch_ary_inf_
; 型変換
dimtype srch_ary_var_, srch_ary_inf_(6)
srch_ary_var_ = TypeCnv(item_, srch_ary_inf_(6))
dim i, 9
dim prm_chk, 2
repeat int(srch_ary_inf_(5) / 3) ; 探索ループ ここから ======================
i(0) = 0 + cnt ; 先頭から 下へ : ↓
i(1) = 0 + ((srch_ary_inf_(5) / 3) * 1 - cnt) ; 1/3 から 上へ : ↑
i(2) = 0 + ((srch_ary_inf_(5) / 3) * 1 + cnt) ; 1/3 から 下へ : ↓
i(3) = 0 + ((srch_ary_inf_(5) / 3) * 2 - cnt) ; 2/3 から 上へ : ↑
i(4) = 0 + ((srch_ary_inf_(5) / 3) * 2 + cnt) ; 2/3 から 下へ : ↓
i(5) = 0 + ((srch_ary_inf_(5) - 1) * 1 - cnt) ; 後尾から 上へ : ↑
; 6分ループ
repeat 3
i(6) = i(5 - cnt)
prm_chk(0) = (srch_ary_var_ = uniary_(srch_ary, i(cnt), srch_ary_inf_))
prm_chk(1) = (srch_ary_var_ = uniary_(srch_ary, i(6), srch_ary_inf_))
if prm_chk(0) {i(7) = i(cnt), 1 : break}
else:if prm_chk(1) {i(7) = i(6), 1 : break}
loop
if i(8) = 1 : break
loop ; 探索ループ ここまで =======================
if i(8) = 1 {return i(7)} else {return -1}
;-------------------------------------------------------------------------------
;
; リストとの線形探索 (多次元配列仕様) (由来 : Multi Dimensional Array Line Search)
;
; val = MDALiSrch(item_, srch_ary)
;
; [ str ] item_ : 探索値
; [array] srch_ary : 変数名 (探索場所)
;
; *** 戻り値 ***
; stat : 配列のオフセット値 (1次元化要素数)
;
#define global ctype MDALiSrch(%1,%2) MDALiSrch_@myarray_srch(str(%1),%2)
;-------------------------------------------------------------------------------
;
; 二分木探索命令
;
; bisrch_ item_, srch_ary, srch_
;
; [ var ] item_ : 探す値
; [array] srch_ary : 探す場所(1次元配列変数) ※注意!※ 昇順ソートされている事が前提!!
; [array] srch_ : 探す場所の配列要素数を受け取る変数
;
; 要素数格納用
; srch_(0) : midle
; srch_(1) : low
; srch_(2) : high
;
#deffunc local bisrch_ var item_, array srch_ary, array srch_
dim srch_, 3
srch_(2) = length(srch_ary) - 1
if (vartype(item_) = 2) { ; 文字列型の場合
str2ASCI item_asci, item_ ; 探索文字列をASCIIコードに変換
repeat
srch_.0 = (srch_.1 + srch_.2) / 2
str2ASCI asci_ary, srch_ary(srch_.0) ; 比較サンプル文字列をASCIIコードに変換
srch_ary_var_ = ASCIcomp(item_asci, asci_ary, 0) ; 探索文字列と比較サンプルのASCIIコードを比較
if ((srch_.1 <= srch_.2) ! 1) {srch_.0 = -1 : break}
else:if (srch_ary_var_ = 0) {break}
else:if (srch_ary_var_ = 1) {srch_.2 = srch_.0 - 1}
else:if (srch_ary_var_ = 2) {srch_.1 = srch_.0 + 1}
loop
}
else { ; 実数型、整数型の場合
repeat
srch_.0 = (srch_.1 + srch_.2) / 2
if ((srch_.1 <= srch_.2) ! 1) {srch_.0 = -1 : break}
else:if (item_ = srch_ary(srch_.0)) {break}
else:if (item_ < srch_ary(srch_.0)) {srch_.2 = srch_.0 - 1}
else {srch_.1 = srch_.0 + 1}
loop
}
return
;-------------------------------------------------------------------------------
;
; 二分木探索命令
;
; bisrch_ item_, srch_ary, srch_
;
; [ var ] item_ : 探す値
; [array] srch_ary : 探す場所(1次元配列変数) ※注意!※ 昇順ソートされている事が前提!!
; [array] srch_ : 探す場所の配列要素数を受け取る変数
;
#define global bisrch(%1,%2,%3)\
midlevar_@myarray_srch=%1:\
bisrch_@myarray_srch midlevar_@myarray_srch,%2,%3
;-------------------------------------------------------------------------------
;
; 二分木探索命令 (多次元配列仕様) (由来 : Multi Dimensional Array Binary Search)
;
; MDABiSrch_ item_, srch_ary, srch_
;
; [ var ] item_ : 探す値
; [array] srch_ary : 探す場所(多次元配列変数) ※注意! 昇順ソートされている事が前提!
; [array] srch_ : 探す場所の配列要素数を受け取る変数
;
; 要素数格納用
; srch_(0) : midle
; srch_(1) : low
; srch_(2) : high
;
#deffunc local MDABiSrch_ str item_, array srch_ary, array srch_
dim_info srch_ary, srch_ary_inf_ ; 配列情報の取得
dim srch_, 4
srch_(2) = srch_ary_inf_(5) - 1
if (srch_ary_inf_(6) = 2) { ; 文字列型の場合##########################
str2ASCI item_asci, item_ ; 探索文字列をASCIIコードに変換
repeat
srch_.0 = (srch_.1 + srch_.2) / 2
; 比較サンプル文字列をASCIIコードに変換
str2ASCI asci_ary, uniary_(srch_ary, srch_.0, srch_ary_inf_)
; 探索文字列と比較サンプルのASCIIコードを比較
srch_ary_var_ = ASCIcomp(item_asci, asci_ary) ; item_asciの方が小さければ1, asci_aryの方が小さければ2, 完全一致は0
if ((srch_.1 <= srch_.2) ! 1) {srch_.0 = -1 : break}
else:if (srch_ary_var_ = 0) {break}
else:if (srch_ary_var_ = 1) {srch_.2 = srch_.0 - 1}
else:if (srch_ary_var_ = 2) {srch_.1 = srch_.0 + 1}
loop
}
else { ; 実数型、整数型の場合####################
; 型変換
srch_ary_var_ = TypeCnv(item_, srch_ary_inf_(6))
repeat
srch_.0 = (srch_.1 + srch_.2) / 2
srch_.3 = uniary_(srch_ary, srch_.0, srch_ary_inf_)
if ((srch_.1 <= srch_.2) ! 1) {srch_.0 = -1 : break}
else:if (srch_ary_var_ = srch_.3) {break}
else:if (srch_ary_var_ < srch_.3) {srch_.2 = srch_.0 - 1}
else {srch_.1 = srch_.0 + 1}
loop
}
return
;-------------------------------------------------------------------------------
;
; 二分木探索命令 (多次元配列仕様) (由来 : Multi Dimensional Array Binary Search)
;
; MDABiSrch_ item_, srch_ary, srch_
;
; [ var ] item_ : 探す値
; [array] srch_ary : 探す場所(多次元配列変数) ※注意! 昇順ソートされている事が前提!
; [array] srch_ : 探す場所の配列要素数を受け取る変数
;
#define global MDABiSrch(%1,%2,%3) MDABiSrch_@myarray_srch str(%1),%2,%3
;-------------------------------------------------------------------------------
;
; ピボット選択関数
; val = get_pivot_(ary1, d1, d2, dim_sw)
;
; [array] ary1 : ピボット選択の対象となる配列変数名
; [ int ] d1 : 選択範囲の始点
; [ int ] d2 : 選択範囲の終点
; [ int ] dim_sw : 多次元配列フラグ (= 0)
;
#defcfunc local get_pivot@myarray_srch array ary1, int d1, int d2, int dim_sw
d_ = (d1 + (d2 - d1) / 2)
if dim_sw { ; 多次元配列の場合
pvt(0) = uniary_(ary1, d1, ary_inf)
pvt(1) = uniary_(ary1, d_, ary_inf)
pvt(2) = uniary_(ary1, d2, ary_inf)
}
else {pvt(0) = ary1(d1), ary1(d_), ary1(d2)}
if (vartype(ary1) ! 2) { ; 数値型の場合######################################
if (pvt.0 < pvt.1) {
if (pvt.1 < pvt.2) {return pvt.1}
else:if (pvt.2 < pvt.0) {return pvt.0} else {return pvt.2}
}
else {
if (pvt.2 < pvt.1) {return pvt.1}
else:if (pvt.0 < pvt.2) {return pvt.0} else {return pvt.2}
}
}
else { ; 文字列型の場合####################################
; それぞれASCIIコードに変換
str2ASCI pvt0, pvt(0) : str2ASCI pvt1, pvt(1) : str2ASCI pvt2, pvt(2)
if (ASCIcomp(pvt0, pvt1) = 1) { ; 第1引数に指定した文字列(pvt0)の方が小さい
if (ASCIcomp(pvt1, pvt2) = 1) {return pvt.1}
else:if (ASCIcomp(pvt2, pvt0) = 1) {return pvt.0} else {return pvt.2}
}
else {
if (ASCIcomp(pvt2, pvt1) = 1) {return pvt.1}
else:if (ASCIcomp(pvt0, pvt2) = 1) {return pvt.0} else {return pvt.2}
}
}
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; クイックソート (数値型)
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;-----------------------------------------------------------
;
; クイックソート (1次元数値型)
;
#deffunc local qsort_uni_num_ array ary1, int frst_idx, int last_idx, int mode_, \
local frst_, local last_
if (frst_idx > last_idx) : return
frst_ = frst_idx ; ピボットの左側
last_ = last_idx ; ピボットの右側
pivot = get_pivot@myarray_srch(ary1, frst_, last_, 0) ; ピボット選出
repeat
; pivotの左側
repeat
if mode_ {if (ary1(frst_) <= pivot) {break} else {frst_++} } ; 降順
else {if (pivot <= ary1(frst_)) {break} else {frst_++} } ; pivotより小さい値が見つかるまで増加
loop
; pivotの右側
repeat
if mode_ {if (pivot <= ary1(last_)) {break} else {last_--} } ; 降順
else {if (ary1(last_) <= pivot) {break} else {last_--} } ; pivotより大きい値が見つかるまで減少
loop
if (last_ <= frst_) {break}
; 入れ替え
_my_tmp_ = ary1(frst_) : ary1(frst_) = ary1(last_) : ary1(last_) = _my_tmp_
frst_++ : last_--
loop
qsort_uni_num_@myarray_srch ary1, frst_idx, frst_ - 1, mode_ ; 左側の再帰
qsort_uni_num_@myarray_srch ary1, last_ + 1, last_idx, mode_ ; 右側の再帰
return
;-----------------------------------------------------------
;
; クイックソート (多次元数値型)
;
#deffunc local qsort_mlt_num_ array ary1, int frst_idx, int last_idx, int mode_, \
local frst_, local last_
if (frst_idx > last_idx) : return
frst_ = frst_idx ; ピボットの左側 (ピボットよりも小さい方)
last_ = last_idx ; ピボットの右側 (ピボットよりも大きい方)
pivot = get_pivot@myarray_srch(ary1, frst_, last_, 1) ; ピボット選出
repeat
; pivotの左側
repeat
frst_val_ = uniary_(ary1, frst_, ary_inf) ; 多次元配列変数を1次元化
if mode_ {if (frst_val_ <= pivot) {break} else {frst_++} } ; 降順
else {if (pivot <= frst_val_) {break} else {frst_++} }
loop
; pivotの右側
repeat
last_val_ = uniary_(ary1, last_, ary_inf) ; 多次元配列変数を1次元化
if mode_ {if (pivot <= last_val_) {break} else {last_--} } ; 降順
else {if (last_val_ <= pivot) {break} else {last_--} }
loop
if (last_ <= frst_) {break}
; 入れ替え
Auniary ary1, last_, frst_val_, ary_inf ; 多次元配列変数の代入用
Auniary ary1, frst_, last_val_, ary_inf ; 多次元配列変数の代入用
frst_++ : last_--
loop
qsort_mlt_num_@myarray_srch ary1, frst_idx, frst_ - 1, mode_ ; 左側の再帰
qsort_mlt_num_@myarray_srch ary1, last_ + 1, last_idx, mode_ ; 右側の再帰
return
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
; クイックソート (文字列型)
;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;-----------------------------------------------------------
;
; クイックソート (1次元文字列型)
;
#deffunc local qsort_uni_str_ array ary1, int frst_idx, int last_idx, int mode_, \
local frst_, local last_
if (frst_idx > last_idx) : return
frst_ = frst_idx ; ピボットの左側 (ピボットよりも小さい方)
last_ = last_idx ; ピボットの右側 (ピボットよりも大きい方)
pivot = get_pivot@myarray_srch(ary1, frst_, last_, 0) ; ピボット選出
str2ASCI pivotasc, pivot ; ピボットをASCIIコードに変換
repeat
; pivotの左側
repeat
str2ASCI frst_asc, ary1(frst_) ; 文字列をASCIIコードに変換
if mode_ {if (ASCIcomp(pivotasc, frst_asc) ! 1) {break} else {frst_++} } ; 降順
else {if (ASCIcomp(pivotasc, frst_asc) ! 2) {break} else {frst_++} }
loop
; pivotの右側
repeat
str2ASCI last_asc, ary1(last_) ; 文字列をASCIIコードに変換
if mode_ {if (ASCIcomp(last_asc, pivotasc) ! 1) {break} else {last_--} } ; 降順
else {if (ASCIcomp(last_asc, pivotasc) ! 2) {break} else {last_--} }
loop
if (last_ <= frst_) {break}
; 入れ替え
_my_tmp_ = ary1(frst_) : ary1(frst_) = ary1(last_) : ary1(last_) = _my_tmp_
frst_++ : last_--
loop
qsort_uni_str_@myarray_srch ary1, frst_idx, frst_ - 1, mode_ ; 左側の再帰
qsort_uni_str_@myarray_srch ary1, last_ + 1, last_idx, mode_ ; 右側の再帰
return
;-----------------------------------------------------------
;
; クイックソート (多次元文字列型)
;
#deffunc local qsort_mlt_str_ array ary1, int frst_idx, int last_idx, int mode_, \
local frst_, local last_
if (frst_idx > last_idx) : return
frst_ = frst_idx ; ピボットの左側 (ピボットよりも小さい方)
last_ = last_idx ; ピボットの右側 (ピボットよりも大きい方)
pivot = get_pivot@myarray_srch(ary1, frst_, last_, 1) ; ピボット選出
str2ASCI pivotasc, pivot ; ピボットをASCIIコードに変換
repeat
; pivotの左側
repeat
frst_val_ = uniary_(ary1, frst_, ary_inf) ; 多次元配列変数を1次元化
str2ASCI frst_asc, frst_val_ ; 文字列をASCIIコードに変換
if mode_ {if (ASCIcomp(pivotasc, frst_asc) ! 1) {break} else {frst_++} } ; 降順
else {if (ASCIcomp(pivotasc, frst_asc) ! 2) {break} else {frst_++} }
loop
; pivotの右側
repeat
last_val_ = uniary_(ary1, last_, ary_inf) ; 多次元配列変数を1次元化
str2ASCI last_asc, last_val_ ; 文字列をASCIIコードに変換
if mode_ {if (ASCIcomp(last_asc, pivotasc) ! 1) {break} else {last_--} } ; 降順
else {if (ASCIcomp(last_asc, pivotasc) ! 2) {break} else {last_--} }
loop
if (last_ <= frst_) {break}
; 入れ替え
Auniary ary1, last_, frst_val_, ary_inf ; 多次元配列変数の代入用
Auniary ary1, frst_, last_val_, ary_inf ; 多次元配列変数の代入用
frst_++ : last_--
loop
qsort_mlt_str_@myarray_srch ary1, frst_idx, frst_ - 1, mode_ ; 左側の再帰
qsort_mlt_str_@myarray_srch ary1, last_ + 1, last_idx, mode_ ; 右側の再帰
return
;-------------------------------------------------------------------------------
;
; 外部インターフェイス用 (マクロでも良い?) (由来 : Multi Dimensional Array Quick Sort)
;
; MDAQSort ary1, mode_, frst_idx, last_idx
;
; [array] ary1 : 配列変数名
; [ int ] mode_ : 昇降順フラグ (= 0, 0:昇順 / 1:降順)
; [ int ] frst_idx : ソート区間の開始地点 (1次元化要素数)
; [ int ] last_idx : ソート区間の終了地点 (1次元化要素数)
;
#deffunc MDAQSort array ary1, int mode_, int frst_idx, int last_idx, \
local last_idx_
; 配列情報の取得
dim ary_inf, 7 : dim_info ary1, ary_inf
; 区間が省略された場合はその配列のすべてをソーティングの対象とする
if ((frst_idx = 0) & (last_idx = 0)) {last_idx_ = ary_inf(5) - 1} else {last_idx_ = last_idx}
if ((ary_inf.4 = 1) & (ary_inf.6 ! 2)) {qsort_uni_num_@myarray_srch ary1, frst_idx, last_idx_, mode_}
else:if ((ary_inf.4 = 1) & (ary_inf.6 = 2)) {qsort_uni_str_@myarray_srch ary1, frst_idx, last_idx_, mode_}
else:if ((ary_inf.4 > 1) & (ary_inf.6 ! 2)) {qsort_mlt_num_@myarray_srch ary1, frst_idx, last_idx_, mode_}
else:if ((ary_inf.4 > 1) & (ary_inf.6 = 2)) {qsort_mlt_str_@myarray_srch ary1, frst_idx, last_idx_, mode_}
return
;-----------------------------------------------------------
;
; クイックソート (汎用型)
;
#deffunc local universal_qsort_@myarray_srch array ary1, int frst_idx, int last_idx, int mode_, \
local frst_, local last_
if (last_idx < frst_idx) : return
frst_ = frst_idx ; ピボットの左側 (ピボットよりも小さい方)
last_ = last_idx ; ピボットの右側 (ピボットよりも大きい方)
pivot = get_pivot@myarray_srch(ary1, frst_, last_, 1) ; ピボット選出
; 文字列型の場合はピボットとなった文字列をASCIIコードに変換しておく
if (ary_inf(6) = 2) {str2ASCI pivotasc, pivot}
repeat
; ----------------------------------------------------------------------pivotの左側
repeat
if (ary_inf(4) = 1) {frst_val_ = ary1(frst_)} ; 1次元
else {frst_val_ = uniary_(ary1, frst_, ary_inf)} ; 多次元
if (ary_inf(6) ! 2) { ; 数値型(整数, 実数)の場合
if mode_ {if (pivot >= frst_val_) {break} else {frst_++} } ; 降順
else {if (pivot <= frst_val_) {break} else {frst_++} }
}
else { ; 文字列型の場合
str2ASCI frst_asc, frst_val_
if mode_ {if (ASCIcomp(pivotasc, frst_asc) ! 1) {break} else {frst_++} } ; 降順
else {if (ASCIcomp(pivotasc, frst_asc) ! 2) {break} else {frst_++} }
}
loop
; ----------------------------------------------------------------------
; ----------------------------------------------------------------------pivotの右側
repeat
if (ary_inf(4) = 1) {last_val_ = ary1(last_)} ; 1次元
else {last_val_ = uniary_(ary1, last_, ary_inf)} ; 多次元
if (ary_inf(6) ! 2) { ; 数値型(整数, 実数)の場合
if mode_ {if (last_val_ >= pivot) {break} else {last_--} } ; 降順
else {if (last_val_ <= pivot) {break} else {last_--} }
}
else { ; 文字列型の場合
str2ASCI last_asc, last_val_
if mode_ {if (ASCIcomp(last_asc, pivotasc) ! 1) {break} else {last_--} } ; 降順
else {if (ASCIcomp(last_asc, pivotasc) ! 2) {break} else {last_--} }
}
loop
; ----------------------------------------------------------------------
if (last_ <= frst_) {break}
; 入れ替え
Auniary ary1, last_, frst_val_, ary_inf
Auniary ary1, frst_, last_val_, ary_inf
frst_++ : last_--
loop
universal_qsort_@myarray_srch ary1, frst_idx, frst_ - 1, mode_ ; 左側の再帰
universal_qsort_@myarray_srch ary1, last_ + 1, last_idx, mode_ ; 右側の再帰
return
;-------------------------------------------------------------------------------
;
; 多機能複合型クイックソート (外部インターフェイス用) (由来 : Multi Function Compound Quick Sort)
; MFCQSort ary1, mode_, frst_idx, last_idx
;
; [array] ary1 : 配列変数名
; [ int ] mode_ : 昇降順フラグ (= 0, 0:昇順 / 1:降順)
; [ int ] frst_idx : ソート区間の開始地点 (1次元化要素数)
; [ int ] last_idx : ソート区間の終了地点 (1次元化要素数)
;
#deffunc MFCQSort array ary1, int mode_, int frst_idx, int last_idx, \
local last_idx_
dim ary_inf, 7 : dim_info ary1, ary_inf
; 区間が省略された場合はその配列のすべてをソーティングの対象とする
if ((frst_idx = 0) & (last_idx = 0)) {last_idx_ = ary_inf(5) - 1} else {last_idx_ = last_idx}
universal_qsort_@myarray_srch ary1, frst_idx, last_idx_, mode_
return
#global // myarray_srch
; myarray_srch モジュール内部で使用する変数の初期化です。
_myarray_srch_init_@myarray_srch
#endif //__myarray_srch__