【C++STL】アルゴリズムにおける各種アルゴリズム解析
48390 ワード
転自:アルゴリズム内の各種アルゴリズム解析
一、巡回防止アルゴリズム
二、findアルゴリズム
int *find(int *begin,int *end,int value)
前閉後合の区間begin,endでは、検索valueが検索されたら最初の条件に合致する要素を返し、そうでなければendポインタを返します.
三、数値アルゴリズム
四、基本アルゴリズム
五、copy()は異なる容器に対して複製する;出力区間と入力区間が重なることについての討論
【注意】dequeコンテナの代わりにvectorコンテナを使用する場合、vector反復器はソースポインタであるため、呼び出されたcopy()アルゴリズムはmommove()で実際のレプリケーションを実行する.
copy_backward(first,last,result);//逆レプリケーション、反復器first-last位置の要素をresult-1から始まる逆区間に逆レプリケーション
補足:プロトタイプ:void memmove(void dest,const void*src,size_t count);
使用法:#include
六、Setメソッド
七、その他のアルゴリズム(演算ロジックが比較的単純なアルゴリズム)
セグメント1のアルゴリズムの例:
セグメント2のアルゴリズムの例:
セグメント3のアルゴリズムの例:
八、複雑なアルゴリズムの例(ソースコードで説明)
一、巡回防止アルゴリズム
for_each( , , )
#include
#include
#include
using namespace std;
template<class T>
struct plus2
{
void operator()(T&x)const
{
x+=2;
}
};
void printElem(int& elem)
{
cout << elem << endl;
}
int main()
{
int ia[]={0,1,2,3,4,5,6};
for_each(ia,ia+7,printElem);//
int ib[]={7,8,9,10,11,12,13};
vector<int> iv(ib,ib+7);
for_each(iv.begin(),iv.end(),plus2<int>());//
for_each(iv.begin(),iv.end(),printElem);//
return 0;
}
二、findアルゴリズム
int *find(int *begin,int *end,int value)
前閉後合の区間begin,endでは、検索valueが検索されたら最初の条件に合致する要素を返し、そうでなければendポインタを返します.
#include
#include
using namespace std;
void printElem(int& elem)
{
cout << elem << endl;
}
int main()
{
int ia[]={0,1,2,3,4,5,6};
int *i= find(ia,ia+7,9);// 9
int *j= find(ia,ia+7,3);// 3
int *end=ia+7;//
if(i == end)
cout<<" 9"<else
cout<<" 9"<if(j == end)
cout<<" 3"<else
cout<<" "<return 0;
}
三、数値アルゴリズム
#include
#include //
#include
#include
#include
#include
using namespace std;
int main()
{
int ia[]={1,2,3,4,5};
vector<int> iv(ia,ia+5);
cout<0)<// 0
cout<0,minus<int>())<//
cout<10)<// 10
cout<10,minus<int>(),plus<int>())<//10-(1+1)-(2+2)
ostream_iterator<int> oite(cout," ");// cout
partial_sum(iv.begin(),iv.end(),oite);// n
cout<int>());// ( )
cout<// -
cout<int>()); // + 。
cout<cout<<pow(10,3)<//
/* VC SGI STL
int n=3;
iota(iv.begin(),iv.end(),n);// n n+1 n+2
for(int i=0;i
return 0;
}
四、基本アルゴリズム
#include
#include
#include
using namespace std;
template<typename T>
struct display
{
void operator()(const T &x)const
{
cout<" ";
}
};
int main()
{
int ia[]={0,1,2,3,4,5,6,7,8};
vector<int> iv1(ia,ia+5);
vector<int> iv2(ia,ia+9);
pair<vector<int>::iterator,vector<int>::iterator> pa;
pa=mismatch(iv1.begin(),iv1.end(),iv2.begin());
cout<<" -- :"<// , end
cout<<" -- :"<//
if(pa.first == iv1.end())
cout<<" "<cout<// 1 , iv1
cout<3])<// 0
cout<3],less<int>())<// 1
fill(iv1.begin(),iv1.end(),9);// iv1 9
for_each(iv1.begin(),iv1.end(),display<int>());
cout<3,6);// iv1 3 6
for_each(iv1.begin(),iv1.end(),display<int>());
cout<vector<int>::iterator ite1=iv1.begin();
vector<int>::iterator ite2=ite1;
advance(ite2,3);// 3
iter_swap(ite1,ite2);//
for_each(iv1.begin(),iv1.end(),display<int>());
cout<<"
max:"<cout<<"min:"<int>());
cout<string stra1[]={"a","b","c"};
string stra2[]={"d","e","f"};
cout<2,stra2,stra2+2)<//
cout<2,stra2,stra2+2,greater<string>())<//
return 0;
}
五、copy()は異なる容器に対して複製する;出力区間と入力区間が重なることについての討論
#include
#include
#include
using namespace std;
template<class T>
struct display
{
void operator()(const T &x)const
{
cout<" ";
}
};
int main()
{
//
int ia1[]={0,1,2,3,4,5,6,7,8};
copy(ia1+2,ia1+7,ia1);// 2-6 1-5
for_each(ia1,ia1+9,display<int>()); //2,3,4,5,6,5,6,7,8
cout<// , 。 copy memmove()
int ia2[]={0,1,2,3,4,5,6,7,8};
copy(ia2+2,ia2+7,ia2+4);// 2-6 4-8
for_each(ia2,ia2+9,display<int>()); //0,1,2,3,2,3,4,5,6
cout<//
int ia3[]={0,1,2,3,4,5,6,7,8};
deque<int> id(ia3,ia3+9);
deque<int>::iterator first=id.begin();
deque<int>::iterator last=id.end();
deque<int>::iterator result=id.begin();
++++first;
cout<cout<cout<int>());//2,3,4,5,6,5,6,7,8
cout<// , memove(),
int ia4[]={0,1,2,3,4,5,6,7,8};
deque<int> ide(ia4,ia4+9);
deque<int>::iterator first1=ide.begin();
deque<int>::iterator last1=ide.end();
deque<int>::iterator result1=ide.begin();
advance(result1,4);//
++++first1;
cout<cout<cout<int>());// 0,1,2,3,2,3,2,3,2 0,1,2,3,2,3,4,5,6
cout<return 0;
}
【注意】dequeコンテナの代わりにvectorコンテナを使用する場合、vector反復器はソースポインタであるため、呼び出されたcopy()アルゴリズムはmommove()で実際のレプリケーションを実行する.
copy_backward(first,last,result);//逆レプリケーション、反復器first-last位置の要素をresult-1から始まる逆区間に逆レプリケーション
補足:プロトタイプ:void memmove(void dest,const void*src,size_t count);
使用法:#include
#include
#include
int main()
{
char s[]="Golden Global View";
memmove(s,s+7,strlen(s)+1-7);
printf("%s",s);
return 0;
}
六、Setメソッド
#include
#include
#include
#include
using namespace std;
template <class T>
struct display
{
void operator()(const T &x)
{
cout<" ";
}
};
int main()
{
int ia1[]={1,3,5,7,9,11};
int ia2[]={1,1,2,3,5,8,13};
multiset<int> s1(ia1,ia1+6);
multiset<int> s2(ia2,ia2+7);
for_each(s1.begin(),s1.end(),display<int>());
cout<int>());
cout<multiset<int>::iterator first1 = s1.begin();
multiset<int>::iterator last1 = s1.end();
multiset<int>::iterator first2 = s2.begin();
multiset<int>::iterator last2 = s2.end();
cout<<"union of s1 and s2: ";
// , max(m,n)。
set_union(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<cout<<"Intersection of s1 and s2: ";
// , min(m,n).
set_intersection(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<cout<<"Intersection of s1 and s2: ";
// S1 s2
set_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<cout<<"Intersection of s1 and s2: ";
// : 。 , ,
// abs(m-n)
set_symmetric_difference(first1,last1,first2,last2,ostream_iterator<int>(cout," "));
cout<return 0;
}
七、その他のアルゴリズム(演算ロジックが比較的単純なアルゴリズム)
セグメント1のアルゴリズムの例:
#include
#include
#include
#include
#include
using namespace std;
template <class T>
struct display
{
void operator()(const T &x)const
{
cout<" ";
}
};
struct even
{
bool operator()(int x)const
{
return x%2?false:true;
}
};
class even_by_two
{
private:
static int _x; //
public:
int operator()()const
{
return _x+=2;
}
};
int even_by_two::_x=0;
int main()
{
int ia[]={0,1,2,3,4,5,6,6,6,7,8};
vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));
// iv
cout<cout<int>())<//
cout<6)<// 6
cout<int>(),7))<// 7 :9
cout<4)<// 4
cout<int>(),2))<// 2 :3
vector<int> iv2(ia+6,ia+8);//6 6
for(int i=0;icout<" ";
cout<// iv iv2 ( ):8
cout<<"find_end:"<3)<// iv iv2 ( ):7
cout<<"find_first_of:"<3)<int>());
cout<// iv2 even_by_two
generate(iv2.begin(),iv2.end(),even_by_two());
for_each(iv2.begin(),iv2.end(),display<int>());
cout<// ( ), even_by_two
generate_n(iv.begin(),3,even_by_two());
for_each(iv.begin(),iv.end(),display<int>()); // _X static
cout<// 6
remove(iv.begin(),iv.end(),6);
for_each(iv.begin(),iv.end(),display<int>()); // _X static
cout<//8 10 3 4 5 7 8 6 6 7 8 ( )
// value 。
vector<int> iv3(12);//
remove_copy(iv.begin(),iv.end(),iv3.begin(),6);
for_each(iv3.begin(),iv3.end(),display<int>()); // _X static
cout<//8 10 3 4 5 7 8 7 8 0 0 ( )
// 6 " " iv 8 10 3 4 5 7 8 6 6 7 8
remove_if(iv.begin(),iv.end(),bind2nd(less<int>,6));
for_each(iv1.begin(),iv1.end(),display<int>()); // _X static
cout<//8 10 7 8 6 6 7 8 6 7 8 ( )
// 7 " " iv3 :8 10 3 4 5 7 8 7 8 0 0 ( )
remove_copy_if(iv.begin(),iv.end(),iv3.begin(),bind2nd(less<int>,7));
for_each(iv3.begin(),iv3.end(),display<int>()); // _X static
cout<//8 10 7 8 7 8 7 8 8 0 0( )
return 0;
}
セグメント2のアルゴリズムの例:
#include
#include
#include
#include
using namespace std;
template <class T>
struct display
{
void operator()(const T &x)const
{
cout<" ";
}
};
int main()
{
int ia[]={8,10,7,8,6,6,7,8,6,7,8};
vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));
// 6 3
replace(iv.begin(),iv.end(),6,3);
for_each(iv.begin(),iv.end(),display<int>()); // _X static
cout<//iv:8 10 7 8 3 3 7 8 3 7 8
vector<int> iv2(12);
// 3 5
replace_copy(iv.begin(),iv.end(),iv2.begin(),3,5);
for_each(iv2.begin(),iv2.end(),display<int>()); // _X static
cout<//iv2:8 10 7 8 5 5 7 8 5 7 8 0( y )
// 5 2
replace_if(iv.begin(),iv.end(),bind2nd(less<int>(),5),2);
for_each(iv.begin(),iv.end(),display<int>()); // _X static
cout<//iv:8 10 7 8 2 5 7 8 2 7 8
// 5 2
replace_copy_if(iv.begin(),iv.end(),iv2.begin(),bind2nd(equal_to<int>(),8),9);
for_each(iv2.begin(),iv2.end(),display<int>()); // _X static
cout<//iv2:9 10 7 8 2 5 7 9 2 7 8 0( )
// ( )
reverse(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<//iv:8 7 2 8 7 5 2 8 7 10 8
// ( )
reverse_copy(iv.begin(),iv.end(),iv2.begin());
for_each(iv2.begin(),iv2.end(),display<int>());
cout<//iv2:8 10 7 8 2 5 7 8 2 7 8 0 ( )
// [bigin,middle) [middle,end)
rotate(iv.begin(),iv.begin()+4,iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<//iv:7 2 2 8 7 10 8 8 7 2 8
// [bigin,middle) [middle,end)
rotate_copy(iv.begin(),iv.begin()+5,iv.end(),iv2.begin());
for_each(iv2.begin(),iv2.end(),display<int>());
cout<//iv2:10 8 8 7 2 8 7 2 2 8 7 0 ( )
// iv 2 8
int ia2[3]={2,8};
vector<int> iv3(ia2,ia2+2);
cout<//2
// iv 2 8
cout<2,8)<//8
// iv 3 8
cout<3,8,less<int>())<//7
swap_ranges(iv3.begin(),iv3.end(),iv.begin());
cout<<"iv:";
for_each(iv.begin(),iv.end(),display<int>());//iv:2 8 2 8 7 10 8 8 7 2 8
cout<cout<<"iv3:";
for_each(iv3.begin(),iv3.end(),display<int>()); //iv3: 7 2
cout<// 2
transform(iv.begin(),iv.end(),iv.begin(),bind2nd(minus<int>(),2));
for_each(iv.begin(),iv.end(),display<int>());//0 6 0 6 5 8 6 6 5 0 6
cout<// iv
transform(iv.begin(),iv.end(),iv.begin(),iv.begin(),plus<int>());
for_each(iv.begin(),iv.end(),display<int>());
cout<//0 12 0 12 10 16 12 12 10 0 12
return 0;
}
セグメント3のアルゴリズムの例:
#include
#include
#include
#include
using namespace std;
template <class T>
struct display
{
void operator()(const T &x)const
{
cout<" ";
}
};
struct even
{
bool operator()(int x)const
{
return x%2?false:true;
}
};
int main()
{
int ia[]={0,1,2,3,4,5,6,6,6,7,8};
vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));
vector<int> iv2(ia+4,ia+8);//4 5 6 6
vector<int> iv3(15);
cout<cout<// iv2 iv
cout<//iv iv2 iv3
merge(iv.begin(),iv.end(),iv2.begin(),iv2.end(),iv3.begin());
for_each(iv3.begin(),iv3.end(),display<int>());
cout<// ,
partition(iv3.begin(),iv3.end(),even());
for_each(iv3.begin(),iv3.end(),display<int>());
cout<//
unique(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<//
unique_copy(iv.begin(),iv.end(),iv3.begin());
for_each(iv3.begin(),iv3.end(),display<int>());
cout<return 0;
}
八、複雑なアルゴリズムの例(ソースコードで説明)
#include
#include
#include
#include
using namespace std;
struct even //
{
bool operator()(int x)const
{
return x%2?false:true;
}
};
template<class T>
struct display
{
void operator()(T &x)const
{
cout<" ";
}
};
int main()
{
int ia[] = {12,17,20,22,23,30,33,40};
vector<int> iv(ia,ia+sizeof(ia)/sizeof(int));
//
cout<21)<//22
cout<21)<//22
//
cout<22)<//22
cout<22)<//23
// ,
cout<33)<//1
cout<34)<//0
// ( )
next_permutation(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<int>());
cout<//
random_shuffle(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<// 4
partial_sort(iv.begin(),iv.begin()+4,iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<// ( )
sort(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<// ( )
sort(iv.begin(),iv.end(),greater<int>());
for_each(iv.begin(),iv.end(),display<int>());
cout<22);
iv.push_back(30);
iv.push_back(17);
//
stable_sort(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<//12 17 17 20 22 22 23 30 30 33 40
pair<vector<int>::iterator,vector<int>::iterator> pairIte;
// 22
pairIte = equal_range(iv.begin(),iv.end(),22);
cout<//lowerbound 22
cout<//upperbound 23
//
pairIte = equal_range(iv.begin(),iv.end(),25);
cout<//lowerbound 30
cout<//upperbound 30
//
random_shuffle(iv.begin(),iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<// iv.begin+5
nth_element(iv.begin(),iv.begin()+5,iv.end());
for_each(iv.begin(),iv.end(),display<int>());
cout<// iv.begin+5
nth_element(iv.begin(),iv.begin()+5,iv.end(),greater<int>());
for_each(iv.begin(),iv.end(),display<int>());
cout<//
stable_sort(iv.begin(),iv.end(),even());
for_each(iv.begin(),iv.end(),display<int>());
cout<return 0;
}