一些有用的stl知识《acm程序设计》
accepted 通过
Presentation Error 输出格式错误
Wrong Answer 答案错误
Runtime Error 多为数组访问越界 程序运行时错误
Time Limit Exceeded 超时 一般为复杂度过高
Output Limit Exceeded 超输出错误
C++ STL (标准模拟库)
容器(A。顺序容器 vector list deque string B。关联容器 set multiset map multimap)
迭代器是用来遍历容器的
算法库 排序算法 不可变序算法 变序性算法 数值算法
#include<algorithm>
sort (a,a+size)
reverse(v.begin(),v.end()) 反向排序
swap(int * a,int *b) 将两个数互换位置
在string尾部添加内容可以直接使用‘+’
也可以用append(“内容”)
string与数之间的相互转换
sstream 头文件
将用到stringstream stream
代码:
<sstream>库定义了三种类:istringstream、ostringstream和stringstream,
分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。
简单起见,我主要以stringstream为中心,因为每个转换都要涉及到输入和输出操作。
注意,<sstream>使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。
而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。
string到int的转换
string result=”10000”;
int n=0;
stream<<result;
stream>>n;//n等于10000
重复利用stringstream对象
如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法;
在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。
在类型转换中使用模板
你可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:
template<class T>
void to_string(string & result,const T& t)
{
ostringstream oss;//创建一个流
oss<<t;//把值传递如流中
result=oss.str();//获取转换后的字符转并将其写入result
}
这样,你就可以轻松地将多种数值转换成字符串了:
to_string(s1,10.5);//double到string
to_string(s2,123);//int到string
to_string(s3,true);//bool到string
可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:
template<class out_type,class in_value>
out_type convert(const in_value & t)
{
stringstream stream;
stream<<t;//向流中传值
out_type result;//这里存储转换结果
stream>>result;//向result中写入值
return result;
}
out_type convert(const in_value & t)
{
stringstream stream;
stream<<t;//向流中传值
out_type result;//这里存储转换结果
stream>>result;//向result中写入值
return result;
}
这样使用convert():
double d;
string salary;
string s=”12.56”;
d=convert<double>(s);//d等于12.56
salary=convert<string>(9000.0);//salary等于”9000”
结论
在过去留下来的程序代码和纯粹的C程序中,传统的<stdio.h>形式的转换伴随了我们很长的一段时间。但是,如文中所述,基于stringstream的转换拥有类型安全和不会溢出这样抢眼的特性,使我们有充足得理由抛弃<stdio.h>而使用<sstream>。<sstream>库还提供了另外一个特性—可扩展性。你可以通过重载来支持自定义类型间的转换。
一些实例:
stringstream通常是用来做数据转换的。
相比c库的转换,它更加安全,自动和直接。
例子一:基本数据类型转换例子 int转string
#include <string>
#include <sstream>
#include <iostream>
int main()
{
std::stringstream stream;
std::string result;
int i = 1000;
stream << i; //将int输入流
stream >> result; //从stream中抽取前面插入的int值
std::cout << result << std::endl; // print the string "1000"
}
int main()
{ std::stringstream stream; std::string result; int i = ; stream << i; //将int输入流 stream >> result; //从stream中抽取前面插入的int值 std::cout << result << std::endl; // print the string "1000" }
运行结果:
001
例子二:除了基本类型的转换,也支持char *的转换。
#include <sstream>
#include <iostream>
int main()
{
std::stringstream stream;
char result[8] ;
stream << 8888; //向stream中插入8888
stream >> result; //抽取stream中的值到result
std::cout << result << std::endl; // 屏幕显示 "8888"
}
int main() { std::stringstream stream; char result[] ; stream << ; //向stream中插入8888 stream >> result; //抽取stream中的值到result std::cout << result << std::endl; // 屏幕显示 "8888" }
002
例子三:再进行多次转换的时候,必须调用stringstream的成员函数clear().
#include <sstream>
#include <iostream>
int main()
{
std::stringstream stream;
int first, second;
stream<< "456"; //插入字符串
stream >> first; //转换成int
std::cout << first << std::endl;
stream.clear(); //在进行多次转换前,必须清除stream
stream << true; //插入bool值
stream >> second; //提取出int
std::cout << second << std::endl;
}
#include <sstream> #include <iostream> int main() { std::stringstream stream; int first, second; stream<< ""; //插入字符串 stream >> first; //转换成int std::cout << first << std::endl; stream.clear(); //在进行多次转换前,必须清除stream stream << true; //插入bool值 stream >> second; //提取出int std::cout << second << std::endl; }
运行clear的结果
003
没有运行clear的结果
004
string中有用来统计某个字符出现的次数
int c1 = count(s.begin(),s.end(),'1');//统计字符1出现的次数
set容器 使用平衡二叉树原理
红黑树
注意在使用set.begin() 的时候其表示的是其开始位置要想取出其中元素要用*s.begin()的形式。
2.4.2 元素插入与中序遍历
#include<iostream>
#include<set>
using namespace std;
int main()
{
set <int> s;//定义元素类型为int 的集合对象s 。当前没有任何元素
s.insert(8);//第一次插入8可以
s.insert(1);
s.insert(12);
s.insert(6);
s.insert(8); //第二次插入8为重复元素,所以将不会插入
//cout<<s[2]<<endl; set 必须要使用迭代器遍历
set<int>::iterator it ;//定义前向迭代器
for(it = s.begin() ;it != s.end() ;it++)
{
cout<<*it<<" " ;
} //中序遍历集合中的所有元素
cout<<endl;
return 0 ;
}
#include<iostream> #include<set> using namespace std; int main() { set <int> s;//定义元素类型为int 的集合对象s 。当前没有任何元素 s.insert();//第一次插入8可以 s.insert(); s.insert(); s.insert(); s.insert(); //第二次插入8为重复元素,所以将不会插入 //cout<<s[2]<<endl; set 必须要使用迭代器遍历 set<int>::iterator it ;//定义前向迭代器 for(it = s.begin() ;it != s.end() ;it++) { cout<<*it<<" " ; } //中序遍历集合中的所有元素 cout<<endl; return ; }
运行结果是: 1 6 8 12
2.4.3 元素的反向遍历
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(8);//第一次插入8可以
s.insert(1);
s.insert(12);
s.insert(6);
s.insert(8); //第二次插入8为重复元素,所以将不会插入
set<int>::reverse_iterator rit;//定义反向迭代器
for(rit=s.rbegin() ;rit=s.rend() ;it++)
{
cout<<*rit<<" ";
} //反向遍历容器内的所有元素
cout<<endl;
return 0 ;
}
#include<iostream> #include<set> using namespace std; int main() { set<int> s; s.insert();//第一次插入8可以 s.insert(); s.insert(); s.insert(); s.insert(); //第二次插入8为重复元素,所以将不会插入 set<int>::reverse_iterator rit;//定义反向迭代器 for(rit=s.rbegin() ;rit=s.rend() ;it++) { cout<<*rit<<" "; } //反向遍历容器内的所有元素 cout<<endl; return ; }
运算结果 :
12 8 6 1
2.4.4元素的删除
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(8);//第一次插入8可以
s.insert(1);
s.insert(12);
s.insert(6);
s.insert(8); //第二次插入8为重复元素,所以将不会插入
s.erase(6);//删除键值为6 的值
set<int>::reverse_iterator rit;//定义反向迭代器
for(rit=s.rbegin() ;rit=s.rend() ;it++)
{
cout<<*rit<<" ";
} //反向遍历容器内的所有元素
cout<<endl;
s.clear() ;//清空集合
cout<<s.size() <<endl;//输出集合的大小
return 0 ;
}
#include<iostream> #include<set> using namespace std; int main() { set<int> s; s.insert();//第一次插入8可以 s.insert(); s.insert(); s.insert(); s.insert(); //第二次插入8为重复元素,所以将不会插入 s.erase();//删除键值为6 的值 set<int>::reverse_iterator rit;//定义反向迭代器 for(rit=s.rbegin() ;rit=s.rend() ;it++) { cout<<*rit<<" "; } //反向遍历容器内的所有元素 cout<<endl; s.clear() ;//清空集合 cout<<s.size() <<endl;//输出集合的大小 return ; }
运行结果:
12 8 1
0
2.4.5
元素的检索
使用find () 如果找到就返回键值的迭代器位置,否则返回最后一个元素后面的位置即end()
#include<iostream>
#include<set>
using namespace std;
int main()
{
set<int> s;
s.insert(8);//第一次插入8可以
s.insert(1);
s.insert(12);
s.insert(6);
s.insert(8); //第二次插入8为重复元素,所以将不会插入
set<int>::iterator it ;
it= s.find(6);//查找键值为6的元素
if(it!=s.end() )//找到
cout<<*it <<endl;//注意不能直接输出it 输出的时候就要输出it里的值
else//没找到
cout<<"not find it"<<endl;
it= s.find(20);
if(it!=s.end() )//找到
cout<<*it<<endl;
else
cout<<"not find it" <<endl;
return 0 ;
}
#include<iostream> #include<set> using namespace std; int main() { set<int> s; s.insert();//第一次插入8可以 s.insert(); s.insert(); s.insert(); s.insert(); //第二次插入8为重复元素,所以将不会插入 set<int>::iterator it ; it= s.find();//查找键值为6的元素 if(it!=s.end() )//找到 cout<<*it <<endl;//注意不能直接输出it 输出的时候就要输出it里的值 else//没找到 cout<<"not find it"<<endl; it= s.find(); if(it!=s.end() )//找到 cout<<*it<<endl; else cout<<"not find it" <<endl; return ; }
输出结果:
6
not find it
2.4.6[重点] 自定义比较函数
A set的元素不是结构体
#include<iostream>
#include<set>
using namespace std;
struct myComp{ //直接在struct后面补全{}不换行的话系统可以自动生成}后的;所以是比较好的代码格式
bool operator () (const int &a,const int &b)
{
if(a!=b) return a>b;
else return a>b;
}
};//自定义比较函数myComp,重载“() ” 操作符
int main()
{
set<int , myComp> s; //定义元素类型为int的集合对象s,当前没有任何元素,采用的比较函数是myComp
s.insert(8);
s.insert(1);
s.insert(12);
s.insert(6);
s.insert(8);//第二次插入8 重复元素不会插入
set<int ,myComp>::iterator it;//定义前向迭代器
for(it = s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
return 0 ;
}
#include<iostream> #include<set> using namespace std; struct myComp{ //直接在struct后面补全{}不换行的话系统可以自动生成}后的;所以是比较好的代码格式 bool operator () (const int &a,const int &b) { if(a!=b) return a>b; else return a>b; } };//自定义比较函数myComp,重载“() ” 操作符 int main() { set<int , myComp> s; //定义元素类型为int的集合对象s,当前没有任何元素,采用的比较函数是myComp s.insert(); s.insert(); s.insert(); s.insert(); s.insert();//第二次插入8 重复元素不会插入 set<int ,myComp>::iterator it;//定义前向迭代器 for(it = s.begin();it!=s.end();it++) { cout<<*it<<" "; } cout<<endl; return ; }
运行结果:
12 8 6 1
B set的元素是结构体
#include<iostream>
#include<string>
#include<set>
using namespace std;
struct Info{
string name;
float score;
bool operator < (const Info &a) const
{
return a.score<score;//按score 由大到小的顺序排列。如果要是由小到大用 > 号
}
};
int main()
{
set<Info> s; //定义Info 类型的元素
Info info;//插入3个元素
info.name = "Jack";
info.score = 80.5;
s.insert(info);
info.name = "Tomi";
info.score = 20.5;
s.insert(info);
info.name = "Nacy";
info.score = 60.5;
s.insert(info);
set<Info>::iterator it;
for(it = s.begin();it!=s.end();it++)
{
cout<<(*it).name<<" : "<<(*it).score<<endl;
}
return 0;
}
#include<iostream> #include<string> #include<set> using namespace std; struct Info{ string name; float score; bool operator < (const Info &a) const { return a.score<score;//按score 由大到小的顺序排列。如果要是由小到大用 > 号 } };
int main()
{ set<Info> s; //定义Info 类型的元素 Info info;//插入3个元素 info.name = "Jack"; info.score = 80.5; s.insert(info); info.name = "Tomi"; info.score = 20.5; s.insert(info); info.name = "Nacy"; info.score = 60.5; s.insert(info); set<Info>::iterator it; for(it = s.begin();it!=s.end();it++)
{
cout<<(*it).name<<" : "<<(*it).score<<endl;
}
return ;
}
运行结果
Jack : 80.5
Nacy : 60.5
Tomi : 20.5
2.5 multiset
multiset 允许插入相同的元素
删除的时候返回为删除元素的个数
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main()
{
multiset <string> ms;
ms.insert("abc");
ms.insert("123");
ms.insert("111");
ms.insert("aaa");
ms.insert("123");
multiset<string>::iterator it;
for(it = ms.begin();it!=ms.end();it++)
{
cout<<(*it)<<endl;
}
int n = ms.erase("123");//返回其删除的元素个数 输出2
cout<<n;
return 0 ;
}
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main()
{
multiset <string> ms;
ms.insert("abc");
ms.insert("");
ms.insert("");
ms.insert("aaa");
ms.insert("");
multiset<string>::iterator it;
for(it = ms.begin();it!=ms.end();it++)
{
cout<<(*it)<<endl;
}
int n = ms.erase("");//返回其删除的元素个数 输出2
cout<<n;
return ;
}
2.6 map 映照容器
由 键值 映照数据 组成
2.6.1 map 创建,元素插入,和遍历访问
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string,float> m;//定义map对象,当前没有任何元素,前面的为键值 后面的为映照数据
m["Jake"]=98.5;
m["Bomi"]=96.0;
m["Kate"]=97.5;//插入元素 map与set一样都默认从小到大排序
map<string,float>::iterator it;
for(it = m.begin();it!=m.end();it++)
{
cout<<(*it).first<<" : "<<(*it).second<<endl;//输出键值与映照数据
}
return 0 ;
}
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string,float> m;//定义map对象,当前没有任何元素,前面的为键值 后面的为映照数据
m["Jake"]=98.5;
m["Bomi"]=96.0;
m["Kate"]=97.5;//插入元素 map与set一样都默认从小到大排序
map<string,float>::iterator it;
for(it = m.begin();it!=m.end();it++)
{
cout<<(*it).first<<" : "<<(*it).second<<endl;//输出键值与映照数据
}
return ;
}
运行结果:
Bomi : 96
Jake : 98.5
Kate : 97.5
注意使用map的时候有可能会产生warning C5786 的错误
所以在头文件前使用#pragma Warning(disable : 4786)
map也可以自己定义比较函数 和set一样
2.6.6
用map实现数字分离
A 字符映照数字
#pragma warning(disable : 4786)
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<char,int> m;//定义map对象,其中没有任何元素、
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
m[''] = ;
/*上面的语句也可以采用循环简化
for(int i = 0; i < 10; i ++)
{
m['0'+i] = j;
}
*/
string sa,sb;
sa = "";
int i ,sum = ;
for( i = ; i<sa.length();i++)
{
sum+=m[sa[i]];
}
cout<<"sum = "<<sum<<endl;
return ;
}
运行结果:
sum = 15
B 数字映照字符
#pragma warning(disable : 4786)
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<int ,char> m;//定义map对象,其中没有任何元素、
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
m[] = '';
/*上面的语句也可以采用循环简化
for(int i = 0; i < 10; i ++)
{
m[i] = '0'+i;
}
*/
int n = ;
string s = "The number is ";
cout<<s + m[n]<<endl;
return ;
}
multimap 与map用法基本一样,但是允许插入重复的键值
#pragma warning(disable : 4786)
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
multimap <string,double> m;
m.insert(pair<string,double>("Jack",300.5));
m.insert(pair<string,double>("Kity",));
m.insert(pair<string,double>("Memi",));
m.insert(pair<string,double>("Jack",));//插入重复的键值 “Jack”
multimap<string,double>:: iterator it ;
for(it = m.begin() ;it!=m.end() ;it++)
{
cout<<(*it).first<<" : "<<(*it).second<<endl;
}
return ;
}
运行结果:
Jack : 300.5
Jack : 360
Kity : 200
Memi : 500
元素的删除:
m.erase("Jack");//删除所有键值为“Jack”的元素
2.8 deque 双端队列容器
可以在头部和尾部都可以插入和删除元素而不需要移动其他元素
用法与vector类似
用头文件#include<deque>
在头部插入新的数的时候会将原有的数覆盖
p.push_front(10);//如果原来的第一个元素是1 则现在为10;
p.push_back(13);//会不断扩充其大小
用d.size()来检测其大小
既可以以数组的方式遍历也可以用迭代器
反向遍历与之前的用法相同
采用pop_front() 方法从头部删除元素
采用pop_back() 方法从尾部删除元素
采用erase() 方法从中间删除元素(参数是迭代器位置《和vector 一样》而set与map的erase函数的参数都是键值)
用clear() 方法清空容器
2.9
list双向链表容器
list对象的节点并不要求在一段连续的内存中所以对于迭代器,只能通过‘++’不可以+n操作这是与vector不同的地方
元素的插入与遍历
#include<iostream>
#include<list>
using namespace std;
int main()
{
list<int> l;
l.push_back();
l.push_back();
l.push_back();//在尾部插入值,链表自动扩充
l.push_front();//在头部插入值,开始有的值不会被覆盖,链表自动扩充
list<int>::iterator it;
it = l.begin();
it++;
l.insert(it,);//在迭代器为1的位置上插入20的键值
for(it = l.begin();it!=l.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
return ;
}
运行结果
8 20 2 1 5
反向遍历同前面
使用remove()方法删除链表中的一个元素,值相同的元素都会被删除
参数为键值
eg
l.remove(1)//键值为1的值都被删除了
使用l.pop_back(2)//参数也为键值,删除尾部的值
使用l.pop_front(2)//参数也为键值,删除头部的值
用erase()的方法删除某迭代器位置上的值
eg 删除第2个元素
it=l.begin();//从0 开始计数
it++;
it++;
l.erase(it);
l.sort( );//对list进行升序排序(不用加algorithm的头文件,list的头文件就包含了)
l.unique()//剔除连续重复元素,只保留一个
eg 2
5 1 1 1 5 1
l.unique() ; 后值为 2 5 1 5 1
2.10
bitset位集合容器
在头文件#include<bitset>中
创建bitset对象的时候必须要指定容器的大小 而且大小一定义,之后就不能再修改了
bitset<100000> b 定义了一个100000位的bit容器且所有的元素值都是0;
设置元素的值
方法 |
功能 |
b.any() |
B中是否存在置为1 的二进制位 |
b.none() |
B中不存在置为1的二进制位 |
b.count() |
B中的置为1的二进制位数 |
b.size() |
B中的二进制位的个数 |
b[pos] |
访问在b中的二进制位 |
b.test(pos) |
B中的在pos处的二进制位数值是否为1 |
b.set() |
把所有的二进制位都设置为1 |
b.set(pos) |
把b中的pos位的值设置为1 |
b.reset() |
把b中的所有值都设置为0 |
b.reset(pos) |
把b中的pos位的值设置为0 |
b.flip() |
把b中的所有值都按位取反 |
b.flip(pos) |
把b中的pos位的值设置按位取反 |
b.to_ulong() |
用b中的同样的二进制位返回一个unsigned long 值 |
os<<b 即可以直接cout<<b<<endl; |
把b中的位集输出到os流 |
2.11
stack堆栈容器
在头文件#include<stack>中
#include<iostream>
#include<stack>
using namespace std;
int main()
{
stack <int> s;
s.push();
s.push();
s.push();
s.push();//元素入栈
cout<<s.top()<<endl;//读取栈顶元素
cout<<s.size()<<endl;//读取元素数量
cout<<s.empty()<<endl;//判断堆栈是否为空
while(s.empty()!=true)
{
cout<<s.top()<<" ";//读取栈顶元素
s.pop();//删除栈顶元素
}
cout<<endl;
return ;
}
运行结果:
9
4
0
9 3 2 1
2.12queue 队列容器
注意:queue插入元素的时候是用的push而不是push_back
注意:queue中没有迭代器,不可以定义迭代器,只有出队和入队的操作
#include<iostream>
#include<queue>
using namespace std;
int main()
{
queue<int> q;
q.push();
q.push();
q.push();
q.push();//入队即插入元素
cout<<q.size() <<endl;//返回队列元素数量
cout<<q.empty()<<endl;//返回队列是否为空,是空为返回真
cout<<q.front() <<endl;//返回队首元素
cout<<q.back() <<endl;//返回队尾元素
while(q.empty() !=true)
{
cout<<q.front() <<" ";
q.pop() ;//队首元素出队
}
cout<<endl;
return ;
}
2.13
priority_queue 优先队列容器
8 要是直接变成小顶堆可以直接priority_queue<int,vector<int>,greater<int>
>que;
priority_queue<int
,vector<int>,greater<int >>que;直接就可以变成是由小到大排序
在头文件#include<queue>中
#include<iostream>
#include<queue>
#include<string>
using namespace std; struct Info{
string name;
float score;
bool operator < (const Info &a) const//重载“<”操作符 ,指定优先规则
{
return a.score<score;//按score由小到大 >为由大到小
}
};
int main()
{
priority_queue<Info> pq;
Info info;//定义结构体变量
info.name = "Jack";
info.score = 68.5;
pq.push(info); info.name = "Bomi";
info.score = 18.5;
pq.push(info); info.name = "Peti";
info.score = ;
pq.push(info);//入队 while(pq.empty()!=true)
{
cout<<pq.tp().name<<" : " <<pq.top().score<<endl;
pq.pop();//出栈
}
return ;
}
#include<iostream>
#include<queue>
#include<string>
using namespace std; struct Info{
string name;
float score;
bool operator < (const Info &a) const//重载“<”操作符 ,指定优先规则
{
return a.score<score;//按score由小到大 >为由大到小
}
};
int main()
{
priority_queue<Info> pq;
Info info;//定义结构体变量
info.name = "Jack";
info.score = 68.5;
pq.push(info); info.name = "Bomi";
info.score = 18.5;
pq.push(info); info.name = "Peti";
info.score = ;
pq.push(info);//入队 while(pq.empty()!=true)
{
cout<<pq.tp().name<<" : " <<pq.top().score<<endl;
pq.pop();//出栈
}
return ;
}
重载()定义优先级
经典的排序::按绩点排序
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std; struct student {
string s;
double d;
}; bool myComp (const student &s1,const student &s2)
{
if(s1.d!=s2.d) return s1.d>s2.d;
if(s1.s!=s2.s) return s1.s<s2.s;
} int main()
{
int n;//班级数
int c;//课程数
double xf;//学分
vector<double>vxf ;//学分向量
int p ;//班级人数
string name;//学生名称
double score ;//成绩
student xs;//学生名称与总学分结构体
vector<student>vxs;//最终学生名称与总学分
cin>>n;
for(int i = ; i< n ; i++ )//处理每一个班
{
cin>>c;//读入课程数量
for(int j = ; j< c; j ++)
{
cin>>xf;
vxf.push_back(xf);
}
cin>>p;//读入班级人数
for(int k = ; k<p ;k++)
{
cin>>name;
xs.s = name ;
xf = 0.0;
for(int m = ;m < c ; m++)
{
cin>>score ;
if(score<) continue ;
xf= xf+ (score-)/*vxf[m];
}
xs.d=xf/;
vxs.push_back(xs);
}
cout<<(i?"\n":"");
cout<<"class"<<i+<<":"<<endl;
sort(vxs.begin(),vxs.end(),myComp);
for(vector<studet>::iterator it = vxs.begin();it<vxs.end();it++)
{
cout<<fixed<<setprecision();
cout<<left<<setw();
cout<<(*it).s<<(*it).d<<endl;
}
vxf.clear();
vxs.clear();
}
return ;
}
按1的个数排序
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
bool myComp (const string &s1,const string &s2)
{
int c1= count(s1.begin(),s1.end(),'');
int c2= count(s2.begin(),s2.end(),'');
return c1!=c2?c1<c2:c1<c2;//彻底修改排序规则,只按1的出现个数排序
//如果1的数量相等,则只按1数量排序
//如果1的数量相等则按出现的先后顺序
//否则会按ASC11码的大小排序
//只能用“>或者< ”不可以用“=”号
}
int main()
{
vector<string> vstr;
string str;
while(cin>>str)
{
vstr.push_back(str);
}
sort(vstr.begin(),vstr.end(),myComp);
vector <string> ::iterator it;
for(it = vstr.begin();it!=vstr.end();it++)
{
cout<<*it<<endl;
}
return ;
}
这里用到的 string中count的函数来统计string中某个字符出现的次数
注意在用到自定义的比较函数中对vector排序时候要将头文件algorithm加上
用到其头文件中的sort函数
查找文件
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
vector<string> v,end;
int main()
{
string s,ss,left,right;
int m , n;
int i ,j, k;
int p,q;
int c = ;
while(cin>>m)
{
c++;//案例数目
if(c>)cout<<endl;
v.clear() ;
for( i= ; i< m ;i++)
{
cin>>s;
v.push_back(s);
}
cin>>n;
for(i = ; i <n ; i++)
{
cin>>ss;
left = "";
right = "";
p = ss.find("*");
for(j = ; j < p ; j++)
{
left += ss[j];
}
for( j = p+ ; j<ss.length() ; j++)
{
right +=ss[j] ;
}
end.clear();
for(j = ; j< v.size() ; j++)
{
if(v[j].size()<(left.size()+right.size()))
continue;
if(left.size()!=)
{
if(v[j].find(left)!=) continue ;
}
if(right.size()!=)
{
reverse(right.begin(),right.end());
reverse(v[j].begin(),v[j].end());
if(v[j].find(right)!=)
{
reverse(right.begin(),right.end());
reverse(v[j].begin(),v[j].end());
continue;
}
reverse(right.begin(),right.end());
reverse(v[j].begin(),v[j].end());
}
end.push_back(v[j]);
}
for(k = ;k<end.size() ;k++)
{
cout<<end[k];
if(k!=end.size()-)
cout<<", ";
else
cout<<endl;
}
if(end.size()==)
cout<<"FILE NOT FOUND"<<endl;
}
}
return ;
}
测试案例
4
command.com
msdos.sys
io.sys
config.sys
2
com*.com
*.sys
3
a.txt
b.txt
c.txt
1
*.doc
4.45 让气球升起来
#include<iostream>
#include<string>
#include<map>
using namespace std;
map<string,int> m;
int main()
{
int
n ;
while(cin>>n&&n!=0)
{
m.clear()
;
string
s;
while(n--)
{
cin>>s;
if(m.find(s)!=m.end()
)
{
m[s]
= m[s]+1;
}
else
m[s]
= 1;
}
map<string,int>
::iterator i ,j;
j
= m.begin() ;
for(
i = m.begin() ; i <m.end() ; i++)
{
if(
i->second>j->second) j = i ;
}
cout<<j->first<<endl;
}
return
0 ;
}
一些有用的stl知识《acm程序设计》的更多相关文章
- 华南师大 2017 年 ACM 程序设计竞赛新生初赛题解
题解 被你们虐了千百遍的题目和 OJ 也很累的,也想要休息,所以你们别想了,行行好放过它们,我们来看题解吧... A. 诡异的计数法 Description cgy 太喜欢质数了以至于他计数也需要用质 ...
- stl 在 acm中的应用总结
总结一些在acm中常用的小技巧,小函数 之前尝试着总结过很多次.都失败了,因为总是担心不全,理解的也不是很透彻.这次再来一次...其实之前保存了很多的草稿就不发布了,当然,下面说的很不全面,路过的大牛 ...
- 西南科技大学第十一届ACM程序设计大赛发言稿
西南科技大学第十一届ACM程序设计大赛发言稿 各位老师.志愿者及参赛选手: 大家好,我是来自计科学院卓软1301的哈特13,很荣幸今天能站在这里代表参赛选手发言. 回想起来,我参加ACM比赛已经快两年 ...
- 记第五届山东省ACM程序设计比赛——遗憾并非遗憾
记第五届山东省ACM程序设计比赛 5月10日上午9点半左右,我们的队伍从学校出发,一个多小时后到达本次比赛的地点-哈尔滨工业大学. 报道,领材料,吃午饭,在哈工大的校园里逛了逛,去主楼的自习室歇息了一 ...
- 第13届 广东工业大学ACM程序设计大赛 C题 平分游戏
第13届 广东工业大学ACM程序设计大赛 C题 平分游戏 题目描述 转眼间又过了一年,又有一届的师兄师姐要毕业了. 有些师兄师姐就去了景驰科技实习. 在景驰,员工是他们最宝贵的财富.只有把每一个人 ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛--L-用来作弊的药水
链接:https://www.nowcoder.com/acm/contest/90/L 来源:牛客网 1.题目描述 -- 在一个风雨交加的夜晚,来自异世界的不愿透露姓名的TMK同学获得了两种超强药水 ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛--D-psd面试
链接:https://www.nowcoder.com/acm/contest/90/D 来源:牛客网 1.题目描述 掌握未来命运的女神 psd 师兄在拿了朝田诗乃的 buff 后决定去实习. 埃森哲 ...
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛
拖了好久了 链接:https://www.nowcoder.com/acm/contest/90/A来源:牛客网 跳台阶 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K, ...
- c++ stl在acm的入门及使用
stl的全称为Standard Template Library,即为标准模板库,它主要依赖于模板,而不是对象,所以你需要对这个模板进行实例化,选择你要使用的类型.我们用的都是一些简单的容器吧 这里可 ...
随机推荐
- 记一次生产环境Nginx日志骤增的问题排查过程
摘要:众所周知,Nginx是目前最流行的Web Server之一,也广泛应用于负载均衡.反向代理等服务,但使用过程中可能因为对Nginx工作原理.变量含义理解错误,或是参数配置不当导致Nginx工作异 ...
- Linux 学习记录 一(安装、基本文件操作).
Linux distributions主要分为两大系统,一种是RPM方式安装软件的系统,包括Red Hat,Fedora,SuSE等都是这类:一种则是使用Debian的dpkg方式安装软件的 ...
- 724. Find Pivot Index
Given an array of integers nums, write a method that returns the "pivot" index of this arr ...
- [Count the numbers satisfying (m + sum(m) + sum(sum(m))) equals to N]
Given an integer N, the task is to find out the count of numbers M that satisfy the condition M + su ...
- 程序员的自我救赎---1.4.1:核心框架讲解(DAL)
<前言> (一) Winner2.0 框架基础分析 (二)PLSQL报表系统 (三)SSO单点登录 (四) 短信中心与消息中心 (五)钱包系统 (六)GPU支付中心 (七)权限系统 (八) ...
- splay小结—植树结
我要把高级数据结构当爸爸了... ...弱到跪烂了. splay,二叉搜索树的一种,具有稳定变形功能. 二叉搜索树:对于一个节点,都只有不超过2个孩子.其左子树内的点的权值都比这个点小,右子树的点的权 ...
- glibc-commons 依赖解析 版本错误,xxx is duplicate yyy
glibc-commons 安装了两个版本,导致依赖glibc-commons的很多软件包 被安装了两个版本: 解决办法就是 先清除这些重复的已安装的软件,然后执行 yum update 将 glib ...
- Java后端程序员都做些什么?
这个问题来自于QQ网友,一句两句说不清楚,索性写个文章. 我刚开始做Web开发的时候,根本没有前端,后端之说. 原因很简单,那个时候服务器端的代码就是一切:接受浏览器的请求,实现业务逻辑,访问数据库, ...
- SCOI 2010 序列操作
题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...
- centos虚拟机初始化脚本
功能 修改主机名为node. 网卡开机启动并设置ip为静态18.8 更新yum源为国内yum源,并安装vim lrzsz wget man ntpdate软件. 关闭iptables selinux, ...