【ACM】C++入门

目录

引言

C++过渡

1-1 万能头文件

1-2 cin,cout

1-3 &引用

1-4 字符串

1-5 范围for循环

1-6 构造与重载

1-7 模板

练习

2-1

2-2


引言

        C++博大精深,不过对于算法竞赛,我们只需要使用其中很少的特性。本篇仅针对算法竞赛介绍,帮助C到C++过渡。

C++过渡

1-1 万能头文件

#include<bits/stdc++.h>
using namespace std;

        第一行:在程序前敲上这串,就不用再记头文件了。

        第二行:接下来介绍的函数中,如std::cin,std::cout,以及STL中的std::vector等,需要这行代码以省去“std::”的部分。

        总之记住这两行就对了。

        温馨提醒:仅算法竞赛。未来做项目老老实实敲头文件。

1-2 cin,cout

        这是输入与输出,相比C而言最大的优势是不用再记%d、%s等占位符。

int a, b;

scanf("%d%d", &a, &b);//C版本
cin >> a >> b;//C++版本

printf("%d %d\n", a, b);//C版本
cout << a << " " << b << endl;//C++版本

        cin/cout注意箭头方向。endl可以记忆为“endline”缩写。

1-3 &引用

        C语言在函数内对实参的操作通过指针实现,而C++提供了“引用”。(不觉得没有指针的代码更自然吗)

//C版本
void swap2(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

//C++版本
void swap2(int &x, int &y) {
    int temp = x;
    x = y;
    y = temp;
}

        为什么不叫“swap”?因为C++自带的swap函数不仅可以交换int,double等,甚至还可以交换结构体。我们很快就会学到如何编写这样强大的函数。

1-4 字符串

        C++提供一个可被cin/cout直接读写的字符串类型:string类型。当用cin读取时遇空格视为结束。想读取整行可用getline()。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line;
	while(getline(cin, line)){//相当于C的fgets
		int sum = 0, x;
		stringstream ss(line);//创建"字符串流"(类似于cin)
		while(ss >> x){
			sum += x; 
			cout << sum << endl; 
		}
	}
	return 0;
}

1-5 范围for循环

        通过类似for(int a: b)的形式可以从头到尾访问b容器。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line{"abcde"};
	for(char a : line){
		a = toupper(a);//转大写,tolower()转小写
        cout << a;
	}
    cout << endl;
	cout << line << endl;//看看结果?
	return 0;
}

        需要修改容器中的元素,或者你想避免复杂类型对象的不必要拷贝时,应该使用&。

#include<bits/stdc++.h>
using namespace std; 

int main(){
	string line{"abcde"};
	for(char &a : line){//使用&
		a = toupper(a);
	}
    cout << line << endl;
	return 0;
}

        不需要修改容器中的元素,且元素类型是复杂类型(如std::string或用户定义的类)时,最好使用const &,可以避免不必要的拷贝。

#include<bits/stdc++.h>
using namespace std;

struct Person {
    string name;
    int age;
};

int main() {
    vector<Person> people = {//vector是变长数组
        {"Alice", 30},
        {"Bob", 25},
        {"Charlie", 35}
    };
    for (const auto &person : people) {
        cout << person.name << " is " << person.age << " years old." << endl;
    }
    return 0;
}

        当然,完全可以使用传统形式:

#include<bits/stdc++.h>
using namespace std; 

int main() {
	string line = "Hello, World!";
	for (size_t i = 0; i < line.length(); ++i) {//对于.length(),.begin等其返回值为size_t类型
		line[i] = tolower(line[i]);
	}
	cout << line << endl; 	
	return 0;
}

1-6 构造与重载

#include<bits/stdc++.h>
using namespace std;

struct Point {
	int x, y;
	// 带有默认参数的构造函数
	Point(int x=0, int y=0) : x(x), y(y) {}//觉得难以理解可以试试y(y),  x(x) 以及 x(y), y(x) 会发生什么
};

// 重载+运算符,使其能够处理Point对象的加法
Point operator+(const Point& A, const Point& B) {//不修改地引用传递参数以避免不必要的复制,特别是对于大型对象。
	return Point(A.x + B.x, A.y + B.y);
}

// 重载<<运算符以输出Point对象
ostream& operator<<(ostream& out, const Point& p) {
	out << "(" << p.x << "," << p.y << ")";
	return out;
}

int main() {
	Point a, b(1, 2);//此时a为(0, 0)
	a.x = 3;
	
	cout << a + b << endl;
	return 0;
}

        上段代码展示了构造函数与重载操作符的部分特性(冰山一角)。看不懂没关系,在未来很长的一段时间内,读者完全可以避开这些用法。在一段时间的沉淀后,欢迎深入研究它们的特性。

1-7 模板

        看一个简单点函数:

int add(int a, int b){
	return a+b;
}

        函数没什么问题,但有局限——double怎么办?我们的Point数组(1-6)怎么办?

        我们稍作修改:

template <typename T>
T add(T a, T b){
	return a+b;
}

        这样,我们就造了一个“万能”函数。

练习

2-1

        函数reverse()可以实现反转。现在你不能直接使用,尝试用所学知识编写相同功能:要求对于一行任意输入,输出其反转后的字符串。

2-2

        完成任意数据类型Point数组(1-6)(同类型)相加。

        提示:Point</*此处可定义类型*/>

int main(){
    Point<int> a(1,2), b(3,4);
    Point<double> c(1.1, 2.2), d(3.3, 4.4);
    cout << a+b << " " << c+d << endl;
    return 0;
}//请补充代码

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 图论 3 1.1 术语 3 1.2 独立集、覆盖集、支配集之间关系 3 1.3 DFS 4 1.3.1 割顶 6 1.3.2 桥 7 1.3.3 强连通分量 7 1.4 最小点基 7 1.5 拓扑排序 7 1.6 欧拉路 8 1.7 哈密顿路(正确?) 9 1.8 Bellman-ford 9 1.9 差分约束系统(用bellman-ford解) 10 1.10 dag最短路径 10 1.11 二分图匹配 11 1.11.1 匈牙利算法 11 1.11.2 KM算法 12 1.12 网络流 15 1.12.1 最大流 15 1.12.2 上下界的网络的最大流 17 1.12.3 上下界的网络的最小流 17 1.12.4 最小费用最大流 18 1.12.5 上下界的网络的最小费用最小流 21 2 数论 21 2.1 最大公约数gcd 21 2.2 最小公倍数lcm 22 2.3 快速幂取模B^LmodP(O(logb)) 22 2.4 Fermat小定理 22 2.5 Rabin-Miller伪素数测试 22 2.6 Pollard-rho 22 2.7 扩展欧几里德算法extended-gcd 24 2.8 欧拉定理 24 2.9 线性同余方程ax≡b(mod n) 24 2.10 中国剩余定理 25 2.11 Discrete Logging(BL == N (mod P)) 26 2.12 N!最后一个不为0的数字 27 2.13 2^14以内的素数 27 3 数据结构 31 3.1 堆(最小堆) 31 3.1.1 删除最小值元素: 31 3.1.2 插入元素和向上调整: 32 3.1.3 堆的建立 32 3.2 并查集 32 3.3 树状数组 33 3.3.1 LOWBIT 33 3.3.2 修改a[p] 33 3.3.3 前缀和A[1]+…+A[p] 34 3.3.4 一个二维树状数组的程序 34 3.4 线段树 35 3.5 字符串 38 3.5.1 字符串哈希 38 3.5.2 KMP算法 40 4 计算几何 41 4.1 直线交点 41 4.2 判断线段相交 41 4.3 三点外接圆圆心 42 4.4 判断点在多边形内 43 4.5 两圆交面积 43 4.6 最小包围圆 44 4.7 经纬度坐标 46 4.8 凸包 46 5 Problem 48 5.1 RMQ-LCA 48 5.1.1 Range Minimum Query(RMQ) 49 5.1.2 Lowest Common Ancestor (LCA) 53 5.1.3 Reduction from LCA to RMQ 56 5.1.4 From RMQ to LCA 57 5.1.5 An algorithm for the restricted RMQ 60 5.1.6 An AC programme 61 5.2 最长公共子序列LCS 64 5.3 最长上升子序列/最长不下降子序列(LIS) 65 5.3.1 O(n^2) 65 5.3.2 O(nlogn) 66 5.4 Joseph问题 67 5.5 0/1背包问题 68 6 组合数学相关 69 6.1 The Number of the Same BST 69 6.2 排列生成 71 6.3 逆序 72 6.3.1 归并排序求逆序 72 7 数值分析 72 7.1 二分法 72 7.2 迭代法(x=f(x)) 73 7.3 牛顿迭代 74 7.4 数值积分 74 7.5 高斯消元 75 8 其它 77

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值