STLソース解析[アルゴリズム][stlmuric.h]

16485 ワード


stlnumeric.hの中のはすべて数値の計算方で、数値の計算と関係があります.
stlnumeric.hソース:
#ifndef __SGI_STL_INTERNAL_NUMERIC_H
#define __SGI_STL_INTERNAL_NUMERIC_H

__STL_BEGIN_NAMESPACE
/*
	sum (1)	:The default operation is to add the elements up;
            ;
		template <class InputIterator, class T>
		T accumulate (InputIterator first, InputIterator last, T init);

	custom (2):	a different operation can be specified as binary_op;
              binary_op    ;     <stl_function.h>  ,      
		template <class InputIterator, class T, class BinaryOperation>
		T accumulate (InputIterator first, InputIterator last, T init,
					 BinaryOperation binary_op);
*/
//     :       
//  [first,last)     init  
//      
template <class _InputIterator, class _Tp>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init)
{
  __STL_REQUIRES(_InputIterator, _InputIterator);
  for ( ; __first != __last; ++__first)//        
    __init = __init + *__first;//           init 
  return __init;
}
//     :             
template <class _InputIterator, class _Tp, class _BinaryOperation>
_Tp accumulate(_InputIterator __first, _InputIterator __last, _Tp __init,
               _BinaryOperation __binary_op)
{
  __STL_REQUIRES(_InputIterator, _InputIterator);
  for ( ; __first != __last; ++__first)//        
    __init = __binary_op(__init, *__first);//           
  return __init;
}
//     :
/*accumulate example:
	#include <iostream>     // std::cout
	#include <functional>   // std::minus
	#include <numeric>      // std::accumulate

	int myfunction (int x, int y) {return x+2*y;}
	struct myclass {
		int operator()(int x, int y) {return x+3*y;}
	} myobject;

	int main () {
	  int init = 100;
	  int numbers[] = {10,20,30};

	  std::cout << "using default accumulate: ";
	  std::cout << std::accumulate(numbers,numbers+3,init);
	  std::cout << '
'; std::cout << "using functional's minus: "; std::cout << std::accumulate (numbers, numbers+3, init, std::minus<int>()); std::cout << '
'; std::cout << "using custom function: "; std::cout << std::accumulate (numbers, numbers+3, init, myfunction); std::cout << '
'; std::cout << "using custom object: "; std::cout << std::accumulate (numbers, numbers+3, init, myobject); std::cout << '
'; return 0; } Output: using default accumulate: 160 using functional's minus: 40 using custom function: 220 using custom object: 280 */ /* ( ) init sum/multiply (1) template <class InputIterator1, class InputIterator2, class T> T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init); custom (2) template <class InputIterator1, class InputIterator2, class T, class BinaryOperation1, class BinaryOperation2> T inner_product (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, T init, BinaryOperation1 binary_op1, BinaryOperation2 binary_op2); */ // :The two default operations (to add up the result of multiplying the pairs) //may be overridden by the arguments binary_op1 and binary_op2. // :Returns the result of accumulating init with the inner products of the pairs //formed by the elements of two ranges starting at first1 and first2. // : template <class _InputIterator1, class _InputIterator2, class _Tp> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); // , for ( ; __first1 != __last1; ++__first1, ++__first2)、 __init = __init + (*__first1 * *__first2);// init return __init; } // : template <class _InputIterator1, class _InputIterator2, class _Tp, class _BinaryOperation1, class _BinaryOperation2> _Tp inner_product(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first2, _Tp __init, _BinaryOperation1 __binary_op1, _BinaryOperation2 __binary_op2) { __STL_REQUIRES(_InputIterator2, _InputIterator); __STL_REQUIRES(_InputIterator2, _InputIterator); // , for ( ; __first1 != __last1; ++__first1, ++__first2) // __binary_op2 , __binary_op1 __init = __binary_op1(__init, __binary_op2(*__first1, *__first2)); return __init; } // : /*inner_product example: #include <iostream> // std::cout #include <functional> // std::minus, std::divides #include <numeric> // std::inner_product int myaccumulator (int x, int y) {return x-y;} int myproduct (int x, int y) {return x+y;} int main () { int init = 10; int series1[] = {10,20,30}; int series2[] = {1,2,3}; std::cout << "using default inner_product: "; std::cout << std::inner_product(series1,series1+3,series2,init); std::cout << '
'; std::cout << "using functional operations: "; std::cout << std::inner_product(series1,series1+3,series2,init, std::minus<int>(),std::divides<int>()); std::cout << '
'; std::cout << "using custom functions: "; std::cout << std::inner_product(series1,series1+3,series2,init, myaccumulator,myproduct); std::cout << '
'; return 0; } Output: using default inner_product: 150 using functional operations: -20 using custom functions: -56 */ // /* : Assigns to every element in the range starting at result the partial sum of the corresponding elements in the range [first,last). If x represents an element in [first,last) and y represents an element in result, the ys can be calculated as: y0 = x0 y1 = x0 + x1 y2 = x0 + x1 + x2 y3 = x0 + x1 + x2 + x3 y4 = x0 + x1 + x2 + x3 + x4 ... ... ... */ /* : :The default operation is to add the elements up; sum (1) template <class InputIterator, class OutputIterator> OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result); : :operation can be specified as binary_op instead. custom (2) template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator partial_sum (InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op); */ // : template <class _InputIterator, class _OutputIterator, class _Tp> _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) {// __value = __value + *__first;// n *++__result = __value;// } return ++__result; } template <class _InputIterator, class _OutputIterator> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;// *__result = *__first;// // , first return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first)); } // : template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOperation> _OutputIterator __partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) {// __value = __binary_op(__value, *__first);// n __binary_op *++__result = __value;// } return ++__result; } template <class _InputIterator, class _OutputIterator, class _BinaryOperation> _OutputIterator partial_sum(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result; *__result = *__first; // , first return __partial_sum(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } // : /*partial_sum example: #include <iostream> // std::cout #include <functional> // std::multiplies #include <numeric> // std::partial_sum int myop (int x, int y) {return x+y+1;} int main () { int val[] = {1,2,3,4,5}; int result[5]; std::partial_sum (val, val+5, result); std::cout << "using default partial_sum: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '
'; std::partial_sum (val, val+5, result, std::multiplies<int>()); std::cout << "using functional operation multiplies: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '
'; std::partial_sum (val, val+5, result, myop); std::cout << "using custom function: "; for (int i=0; i<5; i++) std::cout << result[i] << ' '; std::cout << '
'; return 0; } Output: using default partial_sum: 1 3 6 10 15 using functional operation multiplies: 1 2 6 24 120 using custom function: 1 4 8 13 19 */ /* : Assigns to every element in the range starting at result the difference between its corresponding element in the range [first,last) and the one preceding it (except for *result, which is assigned *first). If x represents an element in [first,last) and y represents an element in result, the ys can be calculated as: y0 = x0 y1 = x1 - x0 y2 = x2 - x1 y3 = x3 - x2 y4 = x4 - x3 ... ... ... The default operation is to calculate the difference, but some other operation can be specified as binary_op instead. */ /* difference (1) template <class InputIterator, class OutputIterator> OutputIterator adjacent_difference (InputIterator first, InputIterator last, OutputIterator result); custom (2) template <class InputIterator, class OutputIterator, class BinaryOperation> OutputIterator adjacent_difference ( InputIterator first, InputIterator last, OutputIterator result, BinaryOperation binary_op ); */ // : template <class _InputIterator, class _OutputIterator, class _Tp> _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*) { _Tp __value = *__first; while (++__first != __last) {// _Tp __tmp = *__first;// tmp *++__result = __tmp - __value;// ( - ), __value = __tmp;// } return ++__result; } template <class _InputIterator, class _OutputIterator> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;// *__result = *__first;// // __adjacent_difference() return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first)); } // : template <class _InputIterator, class _OutputIterator, class _Tp, class _BinaryOperation> _OutputIterator __adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Tp*, _BinaryOperation __binary_op) { _Tp __value = *__first; while (++__first != __last) {// _Tp __tmp = *__first;// tmp *++__result = __binary_op(__tmp, __value);// , __value = __tmp;// } return ++__result; } template <class _InputIterator, class _OutputIterator, class _BinaryOperation> _OutputIterator adjacent_difference(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _BinaryOperation __binary_op) { __STL_REQUIRES(_InputIterator, _InputIterator); __STL_REQUIRES(_OutputIterator, _OutputIterator); if (__first == __last) return __result;// *__result = *__first;// // __adjacent_difference() return __adjacent_difference(__first, __last, __result, __VALUE_TYPE(__first), __binary_op); } // : /*adjacent_difference example: #include <iostream> // std::cout #include <functional> // std::multiplies #include <numeric> // std::adjacent_difference int myop (int x, int y) {return x+y;} int main () { int val[] = {1,2,3,5,9,11,12}; int result[7]; std::adjacent_difference (val, val+7, result); std::cout << "using default adjacent_difference: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '
'; std::adjacent_difference (val, val+7, result, std::multiplies<int>()); std::cout << "using functional operation multiplies: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '
'; std::adjacent_difference (val, val+7, result, myop); std::cout << "using custom function: "; for (int i=0; i<7; i++) std::cout << result[i] << ' '; std::cout << '
'; return 0; } output: using default adjacent_difference: 1 1 1 2 4 2 1 using functional operation multiplies: 1 2 6 15 45 99 132 using custom function: 1 3 5 8 14 20 23 */ // Returns __x ** __n, where __n >= 0. _Note that "multiplication" // is required to be associative, but not necessarily commutative. //power SGI , STL , n 。 // , 。 , n >= 0 x^n。 // ,"multiplication" (associative), // (commutative)。 template <class _Tp, class _Integer, class _MonoidOperation> _Tp __power(_Tp __x, _Integer __n, _MonoidOperation __opr) { if (__n == 0) return identity_element(__opr); else { while ((__n & 1) == 0) { __n >>= 1; __x = __opr(__x, __x); } _Tp __result = __x; __n >>= 1; while (__n != 0) { __x = __opr(__x, __x); if ((__n & 1) != 0) __result = __opr(__result, __x); __n >>= 1; } return __result; } } // : multiplies<_Tp>() template <class _Tp, class _Integer> inline _Tp __power(_Tp __x, _Integer __n) { return __power(__x, __n, multiplies<_Tp>()); } // Alias for the internal name __power. Note that power is an extension, // not part of the C++ standard. // template <class _Tp, class _Integer, class _MonoidOperation> inline _Tp power(_Tp __x, _Integer __n, _MonoidOperation __opr) { return __power(__x, __n, __opr); } template <class _Tp, class _Integer> inline _Tp power(_Tp __x, _Integer __n) { return __power(__x, __n); } // iota is not part of the C++ standard. It is an extension. //C++11 STL // , value , // [first,last) value, value+1, value+2... template <class _ForwardIter, class _Tp> void iota(_ForwardIter __first, _ForwardIter __last, _Tp __value) { __STL_REQUIRES(_ForwardIter, _Mutable_ForwardIterator); __STL_CONVERTIBLE(_Tp, typename iterator_traits<_ForwardIter>::value_type); while (__first != __last) *__first++ = __value++; } // : /*iota example #include <iostream> // std::cout #include <numeric> // std::iota int main () { int numbers[10]; std::iota (numbers,numbers+10,100); std::cout << "numbers:"; for (int& i:numbers) std::cout << ' ' << i; std::cout << '
'; return 0; } output: numbers: 100 101 102 103 104 105 106 107 108 109 */ __STL_END_NAMESPACE #endif /* __SGI_STL_INTERNAL_NUMERIC_H */ // Local Variables: // mode:C++ // End: