c++解题常用方法

本文深入解析C++标准模板库(STL),涵盖变量命名、输入输出优化、常用算法及容器详解,如vector、map、algorithm等,助你提升C++编程效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对c++常用的解题方法进行记录,主要是STL。


变量名
ans
cnt
sum
num
输入输出
取消cin与stdin的同步

ios::sync_with_stdio(false);这样做了之后要注意不要同时混用cout和printf。
std::cin.tie(0);解除cin与cout的绑定,进一步加快执行效率。

大量的数据读写可能会造成运行超时,所以,使用cin读数据,使用printf输出数据。原因:即使取消同步,coutprintf速度还是有较大差距。

freopen
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
fclose(stdin);
fclose(stdout);
fopen
FILE *fin, *fout;
fin = fopen("in.txt", "rb");
fout = fopen("out.txt", "wb");
fscanf(fin, "%d", &x);
fprintf(fout, "%d", x);
fclose(fin);
fclose(fout);
for
range-based-for
vector<int> vec {1,2,3,4,5,6,7,8,9,10};
for (auto n : vec)
    cout << n;

int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//输出数组的全部空间
for (auto n : arr)
    cout << n;

vector<int> vec {1,2,3,4,5,6,7,8,9,10};
for (auto& n : vec)
	n++;
char
isalpha、isdigit、islower、isupper
isalpha()//字母
isdigit()//数字
islower()//小写字母
isupper()//大写字母
double
sqrt
double sqrt(double x);//平方根
fix、floor、ceil和round
double fix(double x);//朝零方向取整
double round(double x);//四舍五入到最近的整数
double floor(double x);//朝负无穷方向取整
double ceil(double x);//朝正无穷方向取整
数组
memcpy
#include <cstring>
memcpy(b, a, sizeof(a));
memcpy(b, a, sizeof(int) * k);//数组a复制k个元素到数组b
memset
#include <cstring>
memset(a, 0, sizeof(a));
字符串
读取

c

char c = getchar();
gets(str);

c++

cin.get(str).get();//不忽略回车
cin.getline(str);//忽略回车
getline(cin, str);//忽略回车
sscanf

从字符串中读进与指定格式相符的数据。
%[a-z] 匹配a到z中任意字符或字符串
%[ab] 匹配a和b中的一员
%[^a] 取到指定字符集为止的字符串
sscanf("1995:11:18", "%d:%d:%d", &a, &b, &c);

int ret;
char *string;
int  digit;
char buf1[255];
char buf2[255];
char buf3[255];
char buf4[255];

/*1.最简单的用法*/
string = "china beijing 123";
ret = sscanf(string, "%s %s %d", buf1, buf2, &digit);
printf("1.string=%s\n", string);
printf("1.ret=%d, buf1=%s, buf2=%s, digit=%d\n\n", ret, buf1, buf2, digit);
/*
**执行结果:
**1.ret=3, buf1=china, buf2=beijing, digit=123
**可以看出,sscanf的返回值是读取的参数个数
*/

/*2.取指定长度的字符串*/
string = "123456789";
sscanf(string, "%5s", buf1);
printf("2.string=%s\n", string);
printf("2.buf1=%s\n\n", buf1);
/*
**执行结果:
**2.buf1=12345
*/

/*3.取到指定字符为止的字符串*/
string = "123/456";
sscanf(string, "%[^/]", buf1);
printf("3.string=%s\n", string);
printf("3.buf1=%s\n\n", buf1);
/*
**执行结果:
**3.buf1=123
*/

/*4.取到指定字符集为止的字符串*/
string = "123abcABC";
sscanf(string, "%[^A-Z]", buf1);
printf("4.string=%s\n", string);
printf("4.buf1=%s\n\n", buf1);
/*
**执行结果:
**4.buf1=123abc
*/

/*5.取仅包含指定字符集的字符串*/
string = "0123abcABC";
sscanf(string, "%[0-9]%[a-z]%[A-Z]", buf1, buf2, buf3);
printf("5.string=%s\n", string);
printf("5.buf1=%s, buf2=%s, buf3=%s\n\n", buf1, buf2, buf3);
/*
**执行结果:
**5.buf1=123, buf2=abc, buf3=ABC
*/

/*6.获取指定字符中间的字符串*/
string = "ios<android>wp7";
sscanf(string, "%*[^<]<%[^>]", buf1);
printf("6.string=%s\n", string);
printf("6.buf1=%s\n\n", buf1);
/*
**执行结果:
**6.buf1=android
*/

/*7.指定要跳过的字符串*/
string = "iosVSandroid";
sscanf(string, "%[a-z]VS%[a-z]", buf1, buf2);
printf("7.string=%s\n", string);
printf("7.buf1=%s, buf2=%s\n\n", buf1, buf2);
/*
**执行结果:
**7.buf1=ios, buf2=android
*/

/*8.分割以某字符隔开的字符串*/
string = "android-iphone-wp7";
/*
**字符串取道'-'为止,后面还需要跟着分隔符'-',
**起到过滤作用,有点类似于第7点
*/
sscanf(string, "%[^-]-%[^-]-%[^-]", buf1, buf2, buf3);
printf("8.string=%s\n", string);
printf("8.buf1=%s, buf2=%s, buf3=%s\n\n", buf1, buf2, buf3);
/*
**执行结果:
**8.buf1=android, buf2=iphone, buf3=wp7
*/

/*9.提取邮箱地址*/
string = "Email:beijing@sina.com.cn";
sscanf(string, "%[^:]:%[^@]@%[^.].%s", buf1, buf2, buf3, buf4);
printf("9.string=%s\n", string);
printf("9.buf1=%s, buf2=%s, buf3=%s, buf4=%s\n\n", buf1, buf2, buf3, buf4);
/*
**执行结果:
**9.buf1=Email, buf2=beijing, buf3=sina, buf4=com.cn
*/

/*10.过滤掉不想截取或不需要的字符串--补充,
**在%号后面加一*号,代表过滤这个字符串,不读取
*/
string = "android iphone wp7";
sscanf(string, "%s %*s %s", buf1, buf2);
printf("10.string=%s\n", string);
printf("10.buf1=%s, buf2=%s\n\n", buf1, buf2);
/*
**执行结果:
**10.android wp7
*/
sprintf

把格式化的数据写入字符串
sprintf(buffer, "%d:%d:%d", a, b, c);

string和char*转换
char* str = s.c_str();
string s(str);
strlen
int len = strlen();
strcpy、strcmp、strcat
strcpy(a, b);
strcmp(a, b);
strcat(a, b);
容器
string

头文件:<string>

find
string s = "123";
string::size_type pos1 = s.find("4");
if (pos1 == s.npos) printf("not found");
int pos2 = s.find("4");
if (pos2 == -1) printf("not found");
insert
s.insert(2, s2);//在s的下标位置2插入字符串s2
substr
string s("123456");
string s2 = s.substr(1, 3);//截取从下标位置1开始,长度为3个字符组成的串"234"
string s3 = s.substr(1);//截取从下标位置1开始,一直到结尾的串"23456"
erase
string s("123456");
s.erase(1, 3);//删除从标位置1开始的长度为3的字符串
append

也可以用+=实现

s.append(s2);//s后面追加s2
replace
s.replace(1, 3, s2);//从标位置1开始的长度为3的字符串用s2来代替
assign

赋值。也可以用=实现

s.assign(s2);
compare

也可以用< > ==实现.
如果两个字符串相等,那么返回0,调用对象大于参数返回1,小于返回-1。

数值转换

c++11

string和数值转换
to_string(val)把val转换成string
stoi(s,p,b)把字符串s从p开始转换成b进制的int
stol(s,p,b)long
stoul(s,p,b)unsigned long
stoll(s,p,b)long long
stoull(s,p,b)unsigned long long
stof(s,p)float
stod(s,p)double
stold(s,p)long double
s=to_string(100);
int a = stoi("-123");
map

对应的数据结构是红黑树.

插入数据

用insert函数插入数据,当map中有这个关键字时,insert操作是插入数据不了的;但是用数组方式可以覆盖以前该关键字对应的值。

map<int, int> m;
m[1] = 1;//数组方式
m.insert(pair<int, int>(1, 2));//insert插入pair
erase
m.erase(1);//删除关键字为1的键值对
clear

删除所有元素。

unordered_map

对应的数据结构是哈希表,用于高效率查询的情况。
使用方法与map类似。

vector
初始化
vector<int> v;//初始化一个size为0的vector
vector<int> v(10);//初始化size,但每个元素值为默认值
vector<int> v(101);//初始化size,并且设置初始值
int a[5] = {1,2,3,4,5};
vector<int> v(a, a+5);//通过数组地址初始化
vector<int> a(10,1);
vector<int> v(a);//通过同类型的vector初始化
push_back
vector<int> v;
v.push_back(1);

struct Num {
    int a, b;
};
vector<Num> v;
v.push_back({1, 2});//添加结构体或类对象时可以用{}来初始化对象,{}内变量的顺序为结构体或类中成员对象的声明顺序
resize

改变容器的大小,并插入新元素。

void resize (size_type n);
void resize (size_type n, value_type val);//用val来初始化这些新插入的元素
  • 当n小于当前size()值时候,vector首先会减少size()值,保存前n个元素,然后将超出n的元素删除
  • 当n大于当前size()值时候,vector会插入相应数量的元素,使得size()值达到n,并对这些元素进行初始化。
v.resize(5, 1);
algorithm
sort
//默认升序排序
vector<int> v;
sort(v.begin(), v.end());
//使用自己的排序函数
bool cmp(int a, int b) {
    return a > b;
}
sort(v.begin(), v.end(), cmp);
//排序元素是结构体,排序传参建议用“const+引用”传参,这样更快
struct Num {
    int a, b;
};
bool cmp(const Num &n1, const Num &n2) {
    return n1.a == n2.a ? n1.b < n2.b : n1.a > n2.a;//这么写
}
find
vector<int> v;
vector<int>::iterator it = find(v.begin(), v.end(), 1);
int index = it - v.begin();//若找不到,则返回last的位置(last越界)
lower_bound和upper_bound

lower_bound()在first和last中的前闭后开区间进行二分查找,返回大于或等于val的第一个元素位置。如果所有元素都小于val,则返回last的位置(last越界)

pos = lower_bound(a, a + 5, 1) - a
pos = lower_bound(a, a + 5, 1, greater<int>()) - a//在降序数组中查找第一个小于或等于val的第一个元素位置

upper_bound()在first和last中的前闭后开区间进行二分查找,返回大于val的第一个元素位置。如果所有元素都小于val,则返回last的位置(last越界)

pos = upper_bound(a, a + 5, 1) - a
pos = upper_bound(a, a + 5, 1, greater<int>()) - a//在降序数组中查找第一个小于val的第一个元素位置
distance

计算两个iterator的距离(非线性容器的iterator不能加减)

list<int> l;
list<int>::iterator it = find(l.begin(), l.end(), 1);
int dis = distance(l.begin(), it);
functional
greater
sort(a, a+5, greater<int>());//降序排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值