fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace ConsoleApp
  6. {
  7. public class RingBuffer<T> : IEnumerable<T>
  8. {
  9. #region フィールド
  10. T[] data;
  11. int _Count;
  12. #endregion
  13.  
  14. #region コンストラクター
  15. /// <summary>
  16. /// 初期最大容量を指定して初期化
  17. /// </summary>
  18. /// <param name="capacity">初期載大容量</param>
  19. public RingBuffer(int capacity)
  20. {
  21. this.data = new T[capacity];
  22. }
  23.  
  24. public RingBuffer(IList<T> list)
  25. {
  26. this.data = list.ToArray<T>();
  27. _Count = data.Length;
  28. }
  29. #endregion
  30.  
  31. #region プロパティー
  32.  
  33. public int Count
  34. {
  35. get
  36. {
  37. return _Count;
  38. }
  39. }
  40.  
  41. /// <summary>
  42. /// インデクサー
  43. /// </summary>
  44. /// <param name="i">読み書き位置</param>
  45. /// <returns>読み出した要素</returns>
  46. public T this[int i]
  47. {
  48. get
  49. {
  50. if (i < 0)
  51. {
  52. uint a = (uint)-i;
  53. if (a > _Count)
  54. {
  55. a = MathEx.mod(a, (uint)_Count);
  56. if (a == 0) return data[0];
  57. }
  58. return data[_Count - a];
  59. }
  60. return this.data[(int)MathEx.mod((uint)i, (uint)data.Length)];
  61. }
  62. set
  63. {
  64. this.data[(int)MathEx.mod((uint)i, (uint)data.Length)] = value;
  65. }
  66. }
  67.  
  68. #endregion
  69.  
  70. #region 配列操作
  71. /// <summary>
  72. /// 配列を拡張する
  73. /// </summary>
  74. /// <param name="capacity"></param>
  75. private void Extend(int capacity)
  76. {
  77. if ( capacity <= _Count)
  78. throw new ArgumentException("容量が要素の数より少ないか、同じ");
  79.  
  80. Array.Resize(ref data, capacity);
  81. }
  82. /// <summary>
  83. /// 配列の大きさを要素の個数に合わせる
  84. /// </summary>
  85. public void Fit()
  86. {
  87. Array.Resize(ref data, _Count);
  88. }
  89. /// <summary>
  90. /// idx番目の位置に新しい要素を追加
  91. /// </summary>
  92. /// <param name="idx">追加位置</param>
  93. /// <param name="elem">追加する要素</param>
  94. public void Insert(int idx, T elem)
  95. {
  96. if (this._Count <= this.data.Length - 1)
  97. Extend(_Count + 1);
  98.  
  99. Array.Copy(data, idx, data, idx + 1, _Count - idx);
  100. data[idx] = elem;
  101. _Count++;
  102. }
  103.  
  104. /// <summary>
  105. /// 先頭に新しい要素を追加。
  106. /// </summary>
  107. /// <param name="elem">追加する要素</param>
  108. public void InsertFirst(T elem)
  109. {
  110. this.Insert(0, elem);
  111. }
  112.  
  113. /// <summary>
  114. /// 末尾に新しい要素を追加。
  115. /// </summary>
  116. /// <param name="elem">追加する要素</param>
  117. public void InsertLast(T elem)
  118. {
  119. if (this._Count <= this.data.Length - 1)
  120. Extend(_Count + 1);
  121. data[_Count] = elem;
  122. _Count++;
  123. }
  124.  
  125. /// <summary>
  126. /// i 番目の要素を削除。
  127. /// </summary>
  128. /// <param name="i">削除位置</param>
  129. public void Delete(int idx)
  130. {
  131.  
  132. for (int n = idx; n < this._Count - 1; n++)
  133. {
  134. data[n] = data[n + 1];
  135. }
  136.  
  137. _Count--;
  138. }
  139.  
  140. /// <summary>
  141. /// 先頭の要素を削除。
  142. /// </summary>
  143. public void DeleteFirst()
  144. {
  145. //this.top = (this.top + 1) & this.mask;
  146. Delete(0);
  147. }
  148.  
  149. /// <summary>
  150. /// 末尾の要素を削除。
  151. /// </summary>
  152. public void DeleteLast()
  153. {
  154. //this.bottom = (this.bottom - 1) & this.mask;
  155. Delete(_Count - 1);
  156. }
  157.  
  158. #endregion
  159.  
  160. #region 検索
  161. public int FindIndex(Predicate<T> match)
  162. {
  163. for (int idx = 0; idx < data.Length; idx++)
  164. {
  165. if (match(data[idx]))
  166. return idx;
  167. }
  168. return -1;
  169. }
  170.  
  171. public int FindIndex(int startIndex, Predicate<T> match)
  172. {
  173. for (int idx = startIndex; idx < data.Length; idx++)
  174. {
  175. if (match(data[idx]))
  176. return idx;
  177. }
  178. return -1;
  179. }
  180.  
  181. public int FindIndex(int startIndex, int count, Predicate<T> match)
  182. {
  183. for (int idx = startIndex; idx < startIndex + count; idx++)
  184. {
  185. if (match(data[idx]))
  186. return idx;
  187. }
  188. return -1;
  189. }
  190. #endregion
  191.  
  192. #region IEnumerable<T> メンバ
  193.  
  194. public IEnumerator<T> GetEnumerator()
  195. {
  196. for (int i = 0; i < _Count; i++)
  197. {
  198. yield return data[i];
  199. }
  200. }
  201.  
  202. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  203. {
  204. return this.GetEnumerator();
  205. }
  206.  
  207. #endregion
  208. }
  209. }
  210.  
  211. public static class MathEx
  212. {
  213. /// <summary>
  214. /// 剰余の計算
  215. /// </summary>
  216. /// <param name="x">割られる数</param>
  217. /// <param name="y">割る数</param>
  218. /// <returns>余り</returns>
  219. public static uint mod(uint x, uint y)
  220. {
  221. ulong a = x;
  222. ulong b = y;
  223. b = b << 31;
  224. for (int i = 0; i < 32; i++)
  225. {
  226. if (a >= b)
  227. {
  228. a -= b;
  229. }
  230. b = b >> 1;
  231. }
  232. return (uint)a;
  233. }
  234. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty