仿STL的vector,写了一组array操作方法。

阅读更多
文档从MSDN抄过来的,稍稍改了一下。
module array;

struct random_access_iterator(T)
{
private:
	alias random_access_iterator!(T) self_type;
	T[] array;
	size_t pos;

public:
	static self_type opCall(T[] array, size_t pos)
	{
		self_type ret;
		ret.array = array;
		ret.pos   = pos;
		return ret;
	}

	T[] get_array()
	{
		return array;
	}

	size_t get_pos()
	{
		return pos;
	}

	T opCall()
	{
		return array[pos];
	}

	void opAssign(T value)
	{
		array[pos] = value;
	}

	void check_array(T[] array)
	{
		if (array !is this.array)
			throw new Exception("not same array object");
		if (this.pos > array.length)
			throw new Exception("invalid iterator");
	}

	self_type
	opAdd(int delta)
	{
		return self_type(this.array, this.pos + delta);
	}

	self_type
	opAdd_r(int delta)
	{
		return opAdd(delta);
	}

	self_type
	opPostInc()
	{
		return opAddAssign(1);
	}

	self_type
	opAddAssign(int delta)
	{
		this.pos += delta;
		if (this.pos > this.array.length)
			this.pos = this.array.length;
		return *this;
	}

	self_type
	opSub(int delta)
	{
		return self_type(this.array, this.pos - delta);
	}

	self_type
	opSub_r(int delta)
	{
		return opSub(delta);
	}

	self_type
	opPostSub()
	{
		return opSubAssign(1);
	}

	self_type
	opSubAssign(int delta)
	{
		this.pos -= delta;
		if (this.pos > this.array.length)
			this.pos = this.array.length;
		return *this;
	}

	self_type
	opNeg()
	{
		int pos = (-this.pos) % this.array.length;
		return self_type(this.array, pos);
	}

	T opCast()
	{
		return this.array[this.pos];
	}

	int opCmp(self_type rhs)
	{
		if (this.array != rhs.array)
			throw new Exception("can't compare iterators of different array");
		return cast(int)this.pos - cast(int)rhs.pos;
	}

	int opEquals(self_type rhs)
	{
		if (this.array == rhs.array && 
			this.pos == rhs.pos)
			return 1;
		return 0;
	}
}

template iterator(T : T[])
{
	alias random_access_iterator!(T) iterator;
}

/******************************************************************************
 * Returns an element at a specified location in the array.
 *
 * Returns: 
 *     A value to the element subscripted in the argument. 
 *     If pos is greater than the size of the array, at throws an exception. 
 *
 * Params:
 *     array = Array object.
 *     pos   = The subscript or position number of the element to reference 
 *             in the array.
 * 
 * Example:
 * --------------------------------------
 * // array_at.d
 * voud main( )
 * {
 *    int[] v1;
 *    
 *    v1.push_back( 10 );
 *    v1.push_back( 20 );
 * 
 *    int i = v1.at( 0 );
 *    int j = v1.at( 1 );
 *    dout << "The first element is " << i << endl;
 *    dout << "The second element is " << j << endl;
 * }
 * --------------------------------------
 *
 * Output:
 *         The first element is 10
* The second element is 20 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ T at(T)(inout T[] array, int pos) { return array[pos]; } unittest { printf("test array.at\n\0"); int[] array = [1,2,3]; assert(array.at(0) == 1); assert(array.at(1) == 2); assert(array.at(2) == 3); assert(array == [1,2,3]); } /****************************************************************************** * Returns last element of the array. * * Returns: * The last element of the array. If the array is empty, the return * value is undefined. * * Params: * array = Array object. * * Remarks: * When compiling with _SECURE_SCL 1, a runtime error will occur if * you attempt to access an element in an empty array. See Checked * Iterators for more information. * * Example: * ------------------------------------- * // array_back.d * void main() { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 11 ); * * int i = v1.back( ); * * dout << "The last integer of v1 is " << i << endl; * } * ------------------------------------ * * Output: * The last integer of v1 is 11 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * front and back *****************************************************************************/ T back(T)(inout T[] array) { version(_SECURE_SCL) { return array[$-1]; } else { T result; if (!array.empty()) result = array[$-1]; return result; } } unittest { printf("test array.back\n\0"); int[] array = [1,2,3]; int b = array.back(); assert(b == 3); assert(array == [1,2,3]); } /****************************************************************************** * Returns the number of elements that the array could contain without * allocating more storage. * * Returns: The current length of storage allocated for the array. * * Params: * array = Array object. * * Remarks: The member function resize will be more efficient if sufficient * memory is allocated to accommodate it. Use the member function * reserve to specify the amount of memory allocated.
* This function is deprecated. * * Example: * ------------------------------------ * // array_capacity.d * * void main( ) * { * int[] v1; * * for (int i=0; i<16; ++i) * v1.push_back( 1 ); * dout << "The length of storage allocated is " * << v1.capacity( ) << "." << endl; * * v1.push_back( 2 ); * dout << "The length of storage allocated is now " * << v1.capacity( ) << "." << endl; * } * ------------------------------------ * * Output: * The length of storage allocated is 16.
* The length of storage allocated is now 32. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * array.size and array.capacity ******************************************************************************/ // deprecated size_t capacity(T)(inout T[] array) { if (array.length <= 16) return 16; for (size_t i=32; true; i *= 2) { if (i > array.length) return i; if (i > (1 << 30)) return size_t.max; } return size_t.max; } unittest { printf("test array.capacity\n\0"); int[] array = []; assert(array.capacity() == 16); int[] array1 = [1]; assert(array1.capacity() == 16); int[] array2 = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]; assert(array2.capacity() == 16); int[] array3 = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16,17]; assert(array3.capacity() == 32); } /****************************************************************************** * Erases the elements of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_clear.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * dout << "The size of v1 is " << v1.size( ) << endl; * v1.clear( ); * dout << "The size of v1 after clearing is " << v1.size( ) << endl; * } * ------------------------------------ * * Output: * The size of v1 is 3
* The size of v1 after clearing is 0 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ ******************************************************************************/ void clear(T)(inout T[] array) { array.length = 0; } unittest { printf("test array.clear\n\0"); int[] array = [1,2,3]; array.clear(); assert(array.length == 0); } /****************************************************************************** * Tests if the array is empty. * * Returns: * true if the array is empty; false if the array is not empty. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_empty.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * * if ( v1.empty( ) ) * dout << "The array is empty." << endl; * else * dout << "The array is not empty." << endl; * } * ------------------------------------ * Output: * The array is not empty. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ bool empty(T)(inout T[] array) { return 0 == array.length; } unittest { printf("test array.empty\n\0"); int[] array = [1,2,3]; assert(array.empty() == false); int[] array1 = []; assert(array1.empty() == true); } /****************************************************************************** * Returns a random-access iterator to the first element in the container. * * Returns: A random-access iterator addressing the first element in the array * or to the location succeeding an empty array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_begin.d * * void main( ) * { * int[] c1; * iterator!(int[]) c1_Iter; * * c1.push_back( 1 ); * c1.push_back( 2 ); * * c1_Iter = c1.begin( ); * dout << "The first element of c1 is "<< *c1_Iter << endl; * * c1_Iter = 20; * c1_Iter = c1.begin( ); * dout << "The first element of c1 is now "<< c1_Iter << endl; * } * ------------------------------------ * * Output: * The first element of c1 is 1
* The first element of c1 is now 20 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * array.empty, array.erase, and array.push_back *****************************************************************************/ iterator!(T[]) begin(T)(inout T[] array) { return iterator!(T[])(array, 0); } unittest { printf("test array.begin\n\0"); int[] array = [1,2,3]; auto begin = array.begin(); assert(begin == iterator!(int[])(array, 0)); } /****************************************************************************** * Returns a random-access iterator that points just beyond the end of the * array. * * Returns: * random-access iterator to the end of the array object. If the array * is empty, array.end == array.begin. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_end.d * * void main( ) * { * int[] v1; * iterator!(int[]) v1_Iter; * * v1.push_back( 1 ); * v1.push_back( 2 ); * * for ( v1_Iter = v1.begin( ) ; v1_Iter != v1.end( ) ; v1_Iter++ ) * cout << v1_Iter.get << endl; * } * ------------------------------------ * * Output: * 1
* 2 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ iterator!(T[]) end(T)(inout T[] array) { return iterator!(T[])(array, array.length); } unittest { printf("test array.end\n\0"); int[] array = [1,2,3]; auto end = array.end(); assert(end == iterator!(int[])(array, 3)); } /****************************************************************************** * Removes an element in a array from specified position. * * Returns: * An iterator that designates the first element remaining beyond any * elements removed, or a pointer to the end of the array if no such * element exists. * * Params: * array = Array object. * where = Position of the element to be removed from the array. * * Example: * ------------------------------------ * // array_erase.d * * void main( ) * { * int[] v1; * iterator!(int[]) Iter; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * v1.push_back( 40 ); * v1.push_back( 50 ); * * dout << "v1 =" ; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * * v1.erase( v1.begin( ) ); * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << *Iter; * dout << endl; * } * ------------------------------------ * * Output: * v1 = 10 20 30 40 50
* v1 = 20 30 40 50 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * empty, erase, and push_back *****************************************************************************/ iterator!(T[]) erase(T)(inout T[] array, iterator!(T[]) where) { where.check_array(array); for (int i=where.get_pos(); i * v1 = 20 30 40 50
* v1 = 20 50 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * empty, erase, and push_back *****************************************************************************/ /* iterator!(T[]) erase(T)(inout T[] array, iterator!(T[]) first, iterator!(T[]) last) { return null; } */ /****************************************************************************** * Returns a reference to the first element in an array. * * Returns: * The first element in the array object. If the array is empty, the * return is undefined. * * Params: * array = Array object. * * Remarks: * When compiling with _SECURE_SCL 1, a runtime error will occur if you * attempt to access an element in an empty array. See Checked * Iterators for more information. * * Example: * ------------------------------------ * // array_front.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 11 ); * * int i = v1.front( ); * * cout << "The first integer of v1 is "<< i << endl; * } * ------------------------------------ * * Output: * The first integer of v1 is 10 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * front and back *****************************************************************************/ T front(T)(inout T[] array) { version(_SECURE_SCL) { return array[0]; } else { if (!array.empty()) return array[0]; T result; return result; } } unittest { printf("test array.front\n\0"); int[] array = [1,2,3]; int f = array.front(); assert(f == 1); assert(array == [1,2,3]); } /****************************************************************************** * Inserts an element or a number of elements or a range of elements into the * array at a specified position. * * Returns: * The first insert function returns an iterator that points to the * position where the new element was inserted into the array. * * Params: * array = Array object. * where = The position in the array where the first element is * inserted. * value = The value of the element being inserted into the array. * * Remarks: * Any insertion operation can be expensive, see vector Class for a * discussion of array performance. * * Example: * ------------------------------------ * // array_insert.cpp * * int main( ) * { * int[] v1; * iterator!(int[]) Iter; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * dout << "v1 =" ; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * * v1.insert( v1.begin( ) + 1, 40 ); * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * v1.insert( v1.begin( ) + 2, 4, 50 ); * * dout << "v1 ="; * for ( Iter = v1.begin( ) ; Iter != v1.end( ) ; Iter++ ) * dout << " " << Iter.get(); * dout << endl; * * v1.insert( v1.begin( )+1, v1.begin( )+2, v1.begin( )+4 ); * dout << "v1 ="; * for (Iter = v1.begin( ); Iter != v1.end( ); Iter++ ) * dout << " " << Iter.get(); * dout << endl; * } * ------------------------------------ * * Output: * v1 = 10 20 30
* v1 = 10 40 20 30
* v1 = 10 40 50 50 50 50 20 30
* v1 = 10 50 50 40 50 50 50 50 20 30 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ iterator!(T[]) insert(T)(inout T[] array, iterator!(T[]) where, T value) { where.check_array(array); array.length = array.length + 1; for(int i=array.length-1; i>where.get_pos(); i--) array[i] = array[i-1]; array[where.get_pos()] = value; return iterator!(T[])(array, where.get_pos()); } unittest { printf("test array.insert\n\0"); int[] array = [1,2,3]; auto begin = array.begin(); insert!(int)(array, begin, 4); assert(array == [4,1,2,3]); } /****************************************************************************** * Deletes the element at the end of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_pop_back.cpp * * int main( ) * { * int[] v1; * * v1.push_back( 1 ); * dout << v1.back( ) << endl; * v1.push_back( 2 ); * dout << v1.back( ) << endl; * v1.pop_back( ); * dout << v1.back( ) << endl; * } * * Output: * 1
* 2
* 1 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * See_Also: * push_back and pop_back *****************************************************************************/ void pop_back(T)(inout T[] array) { if (array.length) array.length = array.length - 1; } unittest { printf("test array.pop_back\n\0"); int[] array = [1,2,3]; array.pop_back(); assert(array.length == 2); assert(array == [1,2]); array.pop_back(); assert(array.length == 1); assert(array == [1]); array.pop_back(); assert(array.length == 0); array.pop_back(); assert(array.length == 0); } /****************************************************************************** * Adds an element to the end of the array. * * Params: * array = Array object. * value = The element added to the end of the array. * * Example: * ------------------------------------ * // array_push_back.cpp * * void main( ) * { * int[] v1; * * v1.push_back( 1 ); * if ( v1.size( ) != 0 ) * dout << "Last element: " << v1.back( ) << endl; * * v1.push_back( 2 ); * if ( v1.size( ) != 0 ) * dout << "New last element: " << v1.back( ) << endl; * } * ------------------------------------ * * Output: * Last element: 1
* New last element: 2 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * push_back and pop_back
* accumulate, copy, and push_back
* adjacent_difference and push_back
* empty, erase, and push_back *****************************************************************************/ void push_back(T)(inout T[] array, T value) { array ~= value; } unittest { printf("test array.push_back\n\0"); int[] array = [1,2,3]; array.push_back(4); assert(array == [1,2,3,4]); array.push_back(5); assert(array == [1,2,3,4,5]); } /****************************************************************************** * Specifies a new size for a array. * * Params: * array = Array object. * newsize = The new size of the array. * value = The value of new elements added to the array if the new size * is larger that the original size. If the value is omitted, * the new objects are assigned the default value. * * Remarks: * If the container's size is less than the requested size, _newsize, * elements are added to the array until it reaches the requested size. * If the container's size is larger than the requested size, the * elements closest to the end of the container are deleted until the * container reaches the size _newsize. If the present size of the * container is the same as the requested size, no action is taken. * * size reflects the current size of the array. * * Example: * ------------------------------------ * // array_resize.d * * void main( ) * { * int[] v1; * * v1.push_back( 10 ); * v1.push_back( 20 ); * v1.push_back( 30 ); * * v1.resize( 4,40 ); * cout << "The size of v1 is " << v1.size( ) << endl; * cout << "The value of the last object is " << v1.back( ) << endl; * * v1.resize( 5 ); * cout << "The size of v1 is now " << v1.size( ) << endl; * cout << "The value of the last object is now " << v1.back( ) << endl; * } * ------------------------------------ * * Output: * The size of v1 is 4
* The value of the last object is 40
* The size of v1 is now 5
* The value of the last object is now 0 * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void resize(T)(inout T[] array, size_t newsize, T value = T.init) { array.length = newsize; } unittest { printf("test array.resize\n\0"); int[] array = [1,2,3]; array.resize(cast(uint)5); assert(array == [1,2,3,0,0]); array.resize(cast(uint)2); assert(array == [1,2]); } /****************************************************************************** * Reserves a minimum length of storage for a array object, allocating space if * necessary. * * Params: * array = Array object. * count = The minimum length of storage to be allocated for the array. * * Example: * ------------------------------------ * // array_reserve.cpp * * void main( ) * { * int[] v1; * * v1.reserve( 20 ); * } * ------------------------------------ * * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void reverse(T)(inout T[] array, size_t count) { size_t oldlen = array.length; array.length = count; array.length = oldlen; } unittest { printf("test array.reverse can't test\n\0"); } /****************************************************************************** * Returns the number of elements in the array. * * Returns: * The current length of the array. * * Params: * array = Array object. * * Example: * ------------------------------------ * // array_size.d * * voud main( ) * { * int[] v1; * size_t i; * * v1.push_back( 1 ); * i = v1.size( ); * dout << "Vector length is " << i << "." << endl; * * v1.push_back( 2 ); * i = v1.size( ); * dout << "Vector length is now " << i << "." << endl; * } * ------------------------------------ * * Output: * Vector length is 1.
* Vector length is now 2. * * Requirements: * ------------------------------------ * import array; * ------------------------------------ * * See_Also: * size and capacity *****************************************************************************/ size_t size(T)(inout T[] array) { return array.length; } unittest { printf("test array.size\n\0"); int[] array = [1,2,3]; assert(array.size() == 3); int[] array1 = [1,2]; assert(array1.size() == 2); } /****************************************************************************** * Exchanges the elements of two arrays. * * Params: * array = Array object. * right = A array providing the elements to be swapped, or a array * whose elements are to be exchanged with those of the array * _left. * left = A array whose elements are to be exchanged with those of the * array _right. * * Example: * ------------------------------------ * // array_swap.d * void main( ) * { * int[] v1, v2; * * v1.push_back( 1 ); * v1.push_back( 2 ); * v1.push_back( 3 ); * * v2.push_back( 10 ); * v2.push_back( 20 ); * * dout << "The number of elements in v1 = " << v1.size( ) << endl; * dout << "The number of elements in v2 = " << v2.size( ) << endl; * dout << endl; * * v1.swap( v2 ); * * dout << "The number of elements in v1 = " << v1.size( ) << endl; * dout << "The number of elements in v2 = " << v2.size( ) << endl; * } * ------------------------------------ * * Output: * The number of elements in v1 = 3
* The number of elements in v2 = 2
* * The number of elements in v1 = 2
* The number of elements in v2 = 3
* * Requirements: * ------------------------------------ * import array; * ------------------------------------ *****************************************************************************/ void swap(T)(inout T[] left, inout T[] right) { T[] temp = left; left = right; right = temp; } unittest { printf("test array.swap\n\0"); int[] array1 = [1,2,3,4]; int[] array2 = [4,3,2,1]; array1.swap(array2); assert(array1 == [4,3,2,1]); assert(array2 == [1,2,3,4]); } import std.stdio; void main() { int[] a = [1,2,3]; assert(a.at(0) == 1); auto i = a.begin(); auto b = a.end(); while(i != a.end()) { printf("%d\n\0", i()); i ++; } auto iter = a.begin(); writefln(iter()); iter = 5; writefln(a); }

你可能感兴趣的:(算法,C#,C++,C,数据结构)