C ++ 일반 알고리즘
1. 개요
일반 알고리즘은 알고리즘, 숫자 및 기타 헤더 파일에 있습니다.
읽기 전용 알고리즘 :
축적 (beg, end, start)
카운트 (beg, end, n)
vector<int> ve{1,2,3,4,4,5,6,43,2,1,23,4};
auto beg=ve.cbegin();
auto end=ve.cend();
int sum=accumulate(beg,end,0);
cout<<sum<<endl;
cout<<count(beg,end,4)<<endl;
컨테이너 알고리즘 작성 :
알고리즘은 쓰기 작업을 확인하지 않습니다.
fill (beg, end, s) : s를 [beg, end);
fill_n (beg, n, s)
vector<int> ve{1,2,3,4,4,5,6,43,2,1,23,4};
auto beg=ve.begin();
auto end=ve.end();
fill(beg,end,2);
for(int i:ve){
cout<<to_string(i)+" ";
}
cout<<endl;
vector<int> ve{1,2,3,4,4,5,6,43,2,1,23,4};
auto beg=ve.begin();
auto end=ve.end();
fill_n(beg,5,2);
for(int i:ve){
cout<<to_string(i)+" ";
}
cout<<endl;
위의 n이 너무 크면 메모리 오버플로가 발생합니다.
back_insert : 반복자를 삽입하고 삽입 위치를 가리키는 컨테이너에 바인딩 된 반복자를 가져옵니다.
다음 방법은 메모리를 오버플로하지 않습니다.
vector<int> ve{1,2,3,4,4,5,6,43,2,1,23,4};
auto beg=ve.begin();
auto end=ve.end();
auto it=back_inserter(ve);
int i=0;
fill_n(it,10,4);
for(int i:ve){
cout<<to_string(i)+" ";
}
cout<<endl;
알고리즘 복사
copy (begin (a1), end (a1), a2)
어레이 복사
int a1[]={1,2,3,4,5};
int a2[5];
copy(begin(a1),end(a1),a2);
for (int i = 0; i < 5; ++i) {
cout<<a2[i]<<endl;
}
replace (beg, end, oldValue, newValue) :
반복기 범위의 이전 값을 새 값으로 바꿉니다. 정규 표현식은 지원되지 않습니다.
vector<string> ve{"aa","bb","cc","dd","ee","dd","cc","bb","aa"};
auto beg=ve.begin();
auto end=ve.end();
replace(beg,end,"aa","xx");
for(auto s:ve){
cout<<s<<endl;
}
replace_copy (beg, end, back_inserter (veCopy),“aa”,“xx”) :
원래 컨테이너의 값을 변경하지 않고 변경된 값을 다른 컨테이너에 복사합니다.
vector<string> ve{"aa","bb","cc","dd","ee","dd","cc","bb","aa"};
vector<string> veCopy;
auto beg=ve.begin();
auto end=ve.end();
replace_copy(beg,end,back_inserter(veCopy),"aa","xx");
for(auto s:veCopy){
cout<<s<<" ";
}
cout<<endl;
for(auto s:ve){
cout<<s<<" ";
}
cout<<endl;
2. 컨테이너 재 장전 산술
unique (words.begin (), words.end ()) :
반복기 범위의 요소를 재정렬하고 각 요소를 한 번만 저장하고 마지막 고유 요소 뒤의 위치를 반환합니다.
#include<algorithm>
#include<numeric>
using namespace std;
void elimDups(vector<string> &);
int main() {
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
elimDups(ve);
for(string s:ve){
cout<<s<<endl;
}
}
void elimDups(vector<string> &words){
sort(words.begin(),words.end());
auto end_unique=unique(words.begin(),words.end());
words.erase(end_unique,words.end());
}
3. 맞춤형 운영
sort (반복자, 반복기, 프레드 표현식),
정렬 기준으로 함수 전달
#include <iostream>
#include <string>
#include <vector>
#include<algorithm>
#include<numeric>
using namespace std;
void elimDups(vector<string> &);
int main() {
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
sort(ve.begin(),ve.end(),[](const string &s1,const string& s2){return s1.size()<s2.size();});
for(string s:ve){
cout<<s<<endl;
}
}
find_if (ve.begin (), ve.end (), [sz] (const string & s) {return s.size ()> sz;})
아래의 find_if는 람다 식과 일치하는 첫 번째 값을 찾고 캡처 된 값을 사용합니다.
#include <iostream>
#include <string>
#include <vector>
#include<algorithm>
#include<numeric>
using namespace std;
void elimDups(vector<string> &);
int main() {
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
int sz=4;
auto w=find_if(ve.begin(),ve.end(),[sz](const string &s){return s.size()>sz;});
cout<<*w<<endl;
/*for(string s:ve){
cout<<s<<endl;
}*/
}
for_each (ve.begin (), ve.end (), [] (const string & s) {cout << s << "";})
for_each는 반복기 범위의 매개 변수에 대해 람다 표현식의 매개 변수를 수행합니다.
#include <iostream>
#include <string>
#include <vector>
#include<algorithm>
#include<numeric>
using namespace std;
void elimDups(vector<string> &);
int main() {
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
int sz=4;
for_each(ve.begin(),ve.end(),[](const string &s){cout<<s<<" ";});
}
가장 큰 (벡터 <문자열> &, 벡터 :: 크기 _ 유형)
가장 작은 것부터 가장 큰 것까지 컨테이너를 배열하고 사전 순으로 길이가 같은 단어를 정렬합니다.
void biggest(vector<string> &words,vector<string>::size_type sz){
elimDups(words);
stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size();});
auto wc=find_if(words.begin(),words.end(),[sz](const string &a){return a.size()>=sz;});
auto count=words.end()-wc;
cout<<count<<" "<<"words"<<endl;
for_each(wc,words.end(),[](const string &s){cout<<s<<" ";});
cout<<endl;
}
void elimDups(vector<string> &words){
sort(words.begin(),words.end());
auto end_unique=unique(words.begin(),words.end());
words.erase(end_unique,words.end());
}
암시 적 캡처
count_if (ve.begin (), ve.end (), [=] (const string & s) {return s.size ()> 4;})
반복기 범위에서 길이가 4보다 큰 문자열을 찾습니다. = 암시 적 캡처의 문구, 복사 및 참조를 의미합니다.
#include <iostream>
#include <string>
#include <vector>
#include<algorithm>
#include<numeric>
using namespace std;
void elimDups(vector<string> &);
void biggest(vector<string> &,vector<string>::size_type);
int main() {
vector<string>::size_type sz=4;
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
auto n=count_if(ve.begin(),ve.end(),[=](const string &s){return s.size()>4;});
cout<<n<<endl;
}
auto check_sz = bind (check_size, _1, sz) ;
_1 네임 스페이스 자리 표시 자에서 check_size 함수의 첫 번째 매개 변수가 sz에 바인딩됨을 의미합니다.
bind () 함수를 사용하여 함수와 매개 변수를 바인드하십시오.
#include <functional>
using namespace std;
void elimDups(vector<string> &);
bool check_size(const string &a,string::size_type sz);
void biggest(vector<string> &,vector<string>::size_type);
using namespace placeholders;
int main() {
vector<string>::size_type sz=4;
vector<string> ve={"the","quick","fox","jumps","over","the","slow","red","turtle"};
auto check_sz=bind(check_size,_1,sz);
auto n=count_if(ve.begin(),ve.end(),check_sz);
cout<<n<<endl;
}
bool check_size(const string &a,string::size_type sz){
return a.size()>sz;
}
auto isSmaller=bind(compared,_2,_1);
cout<<compared(3,1)<<endl;
cout<<isSmaller(3,1)<<endl;
4. 스트림 반복자
istream_iterator <int>는 입력 스트림에서 데이터를 가져오고 Int_eof는 스트림의 끝을 표시합니다.
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <regex>
#include <algorithm>
#include <numeric>
using namespace std;
int main() {
istream_iterator<int> int_it(std::cin),int_eof;
vector<int> ve(int_it,int_eof);
for(int i:ve){
cout<<i<<" ";
}
}
ostream_iterator
//ostream_iterator<T> out(os) 构造方法,out将类型为T的值写入输入流OS
//ostream_iterator<T> out(os,c) 构造方法,out将类型为T的值写入输入流OS,并在每个值后加一个c
istream_iterator<int> int_it(std::cin),int_eof;
vector<int> ve(int_it,int_eof);
ostream_iterator<int> out_iter(cout," ");
for (auto e:ve) {
//使用迭代器给cout赋值,并将迭代器向后移一位;
*out_iter++=e;
}
파일 입력 스트림의 반복자를 가져옵니다.
#include <iostream>
#include <fstream>
#include <zconf.h>
#include <sstream>
#include <iterator>
#include "resource/PersonInfo.h"
using namespace std;
int main() {
vector<PersonInfo> ve;
PersonInfo personInfo;
ifstream in("D:/CLProj/IO/resource/a.text");
//得到流的迭代器和尾后迭代器,一旦IO遇到错误或读到文件结尾,迭代器的值就会和尾后迭代器相等;
istream_iterator<string> in_iter(in), in_end;
while (in_iter!=in_end){
cout<<*in_iter++<<endl;
}
}
파일 출력 스트림의 반복자를 가져옵니다.
#include <iostream>
#include <fstream>
#include <zconf.h>
#include <sstream>
#include <iterator>
#include "resource/PersonInfo.h"
using namespace std;
int main() {
vector<PersonInfo> ve;
PersonInfo personInfo;
personInfo.setName("何宇");
personInfo.setPhones({"1231221234","12131357624"});
ve.push_back(personInfo);
ofstream out("D:/CLProj/IO/resource/a.text",ofstream::app);
ostream_iterator<string> in_iter(out," ");
for(PersonInfo pI:ve){
*in_iter++=pI.name;
for(auto phone:pI.phones)
*in_iter++=phone;
*in_iter++="\n";
}
}
何必 13788889999 13277778888
吴洋 18955557777 13877772222
鲁中 17833332222 17833332222
郭德纲 13922228888
李云 17233339999 18712348976
汪悦 17233332299 18712444476
何世清 18023458921 13476324587
何宇 1231221234 12131357624
역방향 반복자
#include <iostream>
#include <fstream>
#include <zconf.h>
#include <sstream>
#include <iterator>
#include "resource/PersonInfo.h"
using namespace std;
int main() {
// 反向迭代器的结尾指向迭代器开头之前的一个位置
string s("Hello World!");
auto rbeg=s.crbegin();
auto rend=s.crend();
while (rbeg!=rend){
cout<<*rbeg<<" ";
++rbeg;
}
}
요약하자면 :
unique(beg,end) //排重算法
uniuqe(beg,end,comp)//使用comp来比较两个元素是否相等,即调用==来判断是否相等
find(beg,end,val)//在迭代器范围内寻找变量val第一次出现的位置
find_if(beg,end,pred)//查找第一个令pred判断为真的元素
reverse(beg,end)//反转迭代器内的元素
reverse(beg,end,dest)//将反转后的元素拷贝至dest,不改变原来的值;
remove_if(beg,end,lambda)//lambda表达式为真,则将迭代器范围内的值移除
remove_if(v1.beg,v1.end,back_inserter(v2),pred)//将移除的元素拷贝到v2中
replace(beg,end,oldValue,newValue)//在迭代器范围内使用新值代替旧值
replace_if(beg,end,pred,newValue)//,如果元素使pred为真在迭代器范围内使用新值代替旧值。
replace_copy_if(beg,end,dest,pred,newValue)//如果元素使pred为真在迭代器范围内使用新值代替旧值,并将旧值拷贝至dest中
list和forward_list容器中的算法:
list.merge(list2) 将list2中的元素并入list,并且将List2中的元素删除,两者必须是有序的,合并后使用<排序
list.merge(list2,comp) 将list2中的元素并入list,并且将List2中的元素删除,使用comp中的规则排序
list.remove(val) 删除元素val;
list.remove(val,pred),删除使函数为真的元素
list.reverse(),是list的元素反转;
list.sort() 按照默认顺序以"<"排序
list.sort(comp) 以comp比较大小排序
list.unique() 删除重复元素
list.unique(comp) 使用给定的二元谓词判断是否相等