forked from s520/ATCFS_For_OpenBVE
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseFunc.cs
135 lines (125 loc) · 5.6 KB
/
BaseFunc.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
namespace ATCFS {
internal static class BaseFunc {
/// <summary>指定した値以上の先頭のインデックスを返す</summary>
/// <typeparam name="T">比較する値の型</typeparam>
/// <param name="arr">対象の配列(※ソート済みであること)</param>
/// <param name="start">開始インデックス [inclusive]</param>
/// <param name="end">終了インデックス [exclusive]</param>
/// <param name="value">検索する値</param>
/// <param name="comparer">比較関数(インターフェイス)</param>
/// <returns>指定した値以上の先頭のインデックス</returns>
internal static int LowerBound<T>(T[] arr, int start, int end, T value, IComparer<T> comparer) {
int low = start;
int high = end;
int mid;
while (low < high) {
mid = ((high - low) >> 1) + low;
if (comparer.Compare(arr[mid], value) < 0) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
//引数省略のオーバーロード
internal static int LowerBound<T>(T[] arr, T value) where T : IComparable {
return LowerBound(arr, 0, arr.Length, value, Comparer<T>.Default);
}
/// <summary>指定した値以上の先頭のインデックスを返す</summary>
/// <typeparam name="T">比較する値の型</typeparam>
/// <param name="list">対象のリスト(※ソート済みであること)</param>
/// <param name="start">開始インデックス [inclusive]</param>
/// <param name="end">終了インデックス [exclusive]</param>
/// <param name="value">検索する値</param>
/// <param name="comparer">比較関数(インターフェイス)</param>
/// <returns>指定した値以上の先頭のインデックス</returns>
internal static int LowerBound<T>(List<T> list, int start, int end, T value, IComparer<T> comparer) {
int low = start;
int high = end;
int mid;
while (low < high) {
mid = ((high - low) >> 1) + low;
if (comparer.Compare(list[mid], value) < 0) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
//引数省略のオーバーロード
internal static int LowerBound<T>(List<T> list, T value) where T : IComparable {
return LowerBound(list, 0, list.Count, value, Comparer<T>.Default);
}
/// <summary>指定した値より大きい先頭のインデックスを返す</summary>
/// <typeparam name="T">比較する値の型</typeparam>
/// <param name="arr">対象の配列(※ソート済みであること)</param>
/// <param name="start">開始インデックス [inclusive]</param>
/// <param name="end">終了インデックス [exclusive]</param>
/// <param name="value">検索する値</param>
/// <param name="comparer">比較関数(インターフェイス)</param>
/// <returns>指定した値より大きい先頭のインデックス</returns>
public static int UpperBound<T>(T[] arr, int start, int end, T value, IComparer<T> comparer) {
int low = start;
int high = end;
int mid;
while (low < high) {
mid = ((high - low) >> 1) + low;
if (comparer.Compare(arr[mid], value) <= 0) {
low = mid + 1;
} else {
high = mid;
}
}
return low;
}
//引数省略のオーバーロード
internal static int UpperBound<T>(T[] arr, T value) {
return UpperBound(arr, 0, arr.Length, value, Comparer<T>.Default);
}
/// <summary>
/// 配列への範囲外アクセス時にデフォルト値を返す関数
/// </summary>
/// <typeparam name="T">配列の型</typeparam>
/// <param name="a">配列オブジェクト</param>
/// <param name="index">インデックス</param>
/// <returns>配列の要素またはデフォルト値</returns>
internal static T ArrayGetOrDefault<T>(T[] a, int index) {
if (a.Length != 0) {
if (index < 0) {
return a[0];
} else if (index > a.Length - 1) {
return a.Last();
} else {
return a[index];
}
} else {
return (T)(object)0.0;
}
}
/// <summary>
/// 配列への範囲外アクセス時にデフォルト値を返す関数
/// </summary>
/// <typeparam name="T">配列の型</typeparam>
/// <param name="l">配列オブジェクト</param>
/// <param name="index">インデックス</param>
/// <returns>配列の要素またはデフォルト値</returns>
internal static T ListGetOrDefault<T>(List<T> l, int index) {
if (l.Count() != 0) {
if (index < 0) {
return l[0];
} else if (index > l.Count() - 1) {
return l.Last();
} else {
return l[index];
}
} else {
return (T)(object)0.0;
}
}
}
}