变量,输入输出语句
一个C++程序的大致结构如下 
变量的定义
变量类型: bool : true/false 大小为1Byte char :单引号引起的字符,大小为1Byte int :范围-231~231-1的整数,大小为4Byte float 精度6-7位有效数字的整数,大小为4Byte double 精度14-15位有效数字的浮点数,大小位8Byte
long long :范围-263~263-1的整数,大小为8Byte long double 精度18-19位有效数字的浮点数,大小为16Byte
变量定义:
int a,b = 2, c = 2;
float d = 1.5, e = 1, f = 1.2345e2;
bool g = true, h = false;
char i = 'a',j = 'j';
long long l = 12345678987654321LL;
long double m = 123.45;
输入输出语句
cin ,cout 输入输出语句:
cin >> a >> b;
cout << a+b <<' ' << a*b << endl;
scanf ,printf 输入输出语句
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a,b;
scanf("%d%d",&a,&b);
printf("a*b=%d\na*b=%d",a+b,a*b);
printf("a*b=%.2f")
return 0;
}
cin 和scanf 的区别: cin可以跳过空格,scanf会读入空格,cin执行效率低,scanf执行效率高
类型转换: 运算过程中,精度低的会转化为精度高的
tips: 1.做算法用浮点数时,建议用double,精度高 2.保留有效几位小数,用printf 3.整数,浮点数混在一起乘除,注意整数之间的除法会不会变成整除
using namespace std的作用:
常用头文件:iostream cstring algorithm
printf格式化输出:
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int b = 12;
int c = 123;
printf("%5d\n",a);
printf("%-5d\n",b);
printf("%05d\n",c);
return 0;
}
判断语句
基本if-else语句
#include <iostream>
using namespace std;
int main()
{
int score;
cin >> score;
if(score>60) cout << "及格" << endl;
else cout << "不及格" << endl;
return 0;
}
if else 条件下只有一条语句,可以不加括号,否则要加
常用比较运算符
(1) 大于 > (2) 小于 < (3) 大于等于 >= (4) 小于等于 <= (5) 等于 == (6) 不等于 !=
else if 语句
#include <iostream>
using namespace std;
int main()
{
int grade;
cin >> grade;
if(grade>=85) cout<<'A'<<endl;
else if(grade>=75) cout<<'B'<<endl;
else if(grade>=60) cout<<'C'<<endl;
else cout<<'D'<<endl;
return 0;
}
条件表达式
与: && 或 :|| 非: !
转移字符: \n 换行 \' 单引号字符 \" 双引号字符 %% 字符串中显示%
时间间隔计算总结
AcWing668 游戏时间2 给出两个时间点,计算出间隔的时间数 思路: 将两个时间换算成距离0点0分的分钟数在计算,若结束时间大于开始时间,则间隔的分钟数=结束时间对应的分钟数-开始时间对应的分钟数 若结束时间小于开始时间,说明经过了一天,则间隔的分钟数=结束时间对应的分钟数+1440(一天的分钟数 )-开始时间对应的分钟数
题解代码:
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int a,b,c,d;
cin >> a >> b >> c >> d;
int x = a*60+b;
int y = c*60+d;
if(y>x) printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",(y-x)/60,(y-x)%60);
else printf("O JOGO DUROU %d HORA(S) E %d MINUTO(S)",(y+1440-x)/60,(y+1440-x)%60);
return 0;
}
循环语句
for循环
把控制循环次数的变量从循环体中剥离,基本结构如下: for (init-statement : condition: expression) { statement } init-statement可以是声明语句、表达式、空语句,一般用来初始化循环变量; condition 是条件表达式,和while中的条件表达式作用一样;可以为空,空语句表示true expression 一般负责修改循环变量,可以为空
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
for(int i=1;i<=10;i++)
{
cout << i << endl;
}
return 0;
}
while 循环
循环版的if语句。If语句是判断一次,如果条件成立,则执行后面的语句;while是每次判断,如果成立,则执行循环体中的语句,否则停止。
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int i = 1;
while(i<=10)
{
cout << i << endl;
i++;
}
return 0;
}
do while 循环
do while语句与while语句非常相似。唯一的区别是,do while语句限制性循环体后检查条件。不管条件的值如何,我们都要至少执行一次循环。
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int i = 0;
do
{
i++;
}while(i<0);
cout << i << endl;
int j = 0;
while(j<0)
{
j++;
}
cout << j << endl;
return 0;
}
continue 和 break
break :可以提前从循环中退出,不再执行循环体内的语句 continue :跳到下次循环的开头,不执行循环体内该次循环这条语句后的语句
嵌套循环
打印n阶方阵
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
int n;
cin >> n;
for(int i=0,k=1;i<n;i++)
{
for(int j=0;j<n;j++,k++)
{
cout << k << " " ;
}
cout << endl;
}
return 0;
}
打印菱形:曼哈顿距离
曼哈顿距离:把两个点坐标的 x 坐标相减取绝对值,y 坐标相减取绝对值,再加和
c
=
∣
x
1
?
x
2
∣
+
∣
y
1
?
y
2
∣
c=|x1-x2|+|y1-y2|
c=∣x1?x2∣+∣y1?y2∣ 思路:观察n阶菱形中点的坐标,发现每个点到中心点的曼哈顿距离都小于
?
n
2
?
\lfloor\frac{n}{2}\rfloor
?2n??
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
int n;
cin >> n;
int cx = n/2,cy = n/2;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
if((abs(i-cx)+abs(j-cy))<=n/2) cout << "*";
else cout << " ";
}
cout << endl;
}
return 0;
}
数组
数组的初始化
int a[3] = [0,1,2];
int b[3] = {0,1,1};
int c[5] = {0,1,2};
char d[] = {'a','b','c'};
函数内部定义的数组都是随机赋值的,且数组存储与栈内存中,大小有限制,约为1M 而函数外部定义的数组都初始化为0,且存储在堆内存中,大小可以很大(受内存限制),因此定义较大的数组一般放在函数外面
访问数组
#include <iostream>
using namespace std;
int main()
{
int n,m;
cin >> n >> m;
int a[n];
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cout << a[i] << " ";
return 0;
}
旋转数组
Leecode 189 旋转数组 暴力解法: 旋转一次前,记录下数组的最后一个元素为temp,之后把所有的元素都往后移一个单位,再在空出的第一个位置填上temp
代码如下:
#include <iostream>
using namespace std;
int main()
{
int n,m;
cin >> n >> m;
int a[n];
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<m;i++)
{
int temp=a[n-1];
for(int j=n-1;j>0;j--) a[j]=a[j-1];
a[0] = temp;
}
for(int i=0;i<n;i++) cout << a[i] << " ";
return 0;
}
优化解法: 以数组【1,2,3,4,5】,旋转2次为例
操作 | 数组 |
---|
初始状态 | 【1,2,3,4,5】 | 目标状态 | 【1,2,3,4,5】 | ①将整个数组翻转 | 【5,4,3,2,1】 | ②将对应的前半部分数组翻转 | 【4,5,3,2,1】 | ③将后半部分数组翻转 | 【4,5,1,2,3】 |
代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n,k;
cin >> n >> k;
int a[n];
for(int i=0;i<n;i++) cin>>a[i];
reverse(a,a+n);
reverse(a,a+k);
reverse(a+k,a+n);
for(int i=0;i<n;i++) cout << a[i] << " ";
return 0;
}
多维数组定义与访问
#include <iostream>
using namespace std;
int main()
{
int a[3][4]={{0,1,2,3},
{4,5,6,7},
{8,9,10,11}};
for(int i=0;i<3;i++)
{
for(int j=0;j<4;j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}
memset初始化 memcpy复制
需要先调用cstring 头文件 memset : memset是以字节为单位,初始化内存块。 初始化数组时,格式如下 memset(数组名, 0, sizeof 数组名); // 初始化为全零数组 memcpy :内存拷贝函数,从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,格式如下: memcpy(拷贝目的数组, 拷贝原数组, sizeof 原数组);
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
int a[10],b[10];
for(int i=0;i<10;i++) a[i]=i;
memcpy(b,a,sizeof a);
memset(a,0,sizeof a);
for(int i=0;i<10;i++) cout << b[i] << " ";
cout << endl;
for(int i=0;i<10;i++) cout << a[i] << " ";
return 0;
}
练习题: Acwing 754 平方矩阵II Acwing 756 蛇形矩阵
字符串
字符与整数的联系:ASCII码
每个常用字符都对应一个-128~127的数字,二者之间可以相互转化
#include <iostream>
using namespace std;
int main()
{
for(int i=1;i<128;i++) printf("%d: %c\n",i,(char)i);
return 0;
}
常用ASCII值:’A’-‘Z’ 是65~90,’a’-‘z’是97-122,’0’-‘9’是48-57。 字符可以参与运算,运算时会将其当做整数:
字符数组
字符数组的定义:
#include <iostream>
using namespace std;
int main()
{
char a1[] = {'c','+','+'};
char a2[] = {'c','+','+','\0'};
char a3[] = "c++";
cout << sizeof a3 << endl;
return 0;
}
字符数组的输入输出
cin输入 cout输出 :
char a[100],b[100];
cin >> a;
scanf("%s",b);
cin >> a+1;
输出:cout printf ,puts :
#include <iostream>
using namespace std;
int main()
{
char a1[] = "ABCDEFG";
cout << a1 << endl;
printf("%s\n",a1);
puts(a1);
cout << a1+1 << endl;
printf("%s\n",a1+1);
return 0;
}
cin scanf 都是遇到空格,回车就停止了
获取整行字符
fgets() :可读入到字符数组中,fgets(字符数组名,读取长度,stdin)
注意:fgets()会把回车读进来
char a[100],b[100];
fgets(a,100,stdin);
getline() :读到string里,getline(cin,读入的string变量名)
string s;
getline(cin,s);
字符数组的常用操作
strlen() strcmp() strcpy()
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char a[100],b[100];
cin >> a;
strcpy(b, a);
cout << strlen (a) << endl;
cout << strcmp(a,"abc") << endl;
cout << b << endl;
return 0;
}
遍历字符数组:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int main()
{
char a[100];
cin >> a;
for(int i=0,len = strlen(a);i<len;i++) cout << a[i] << endl;
return 0;
}
string
string 的定义
#include <iostream>
using namespace std;
int main()
{
string s1;
string s2 = "ABCD";
string s3 = s2;
string s4(10,'c');
return 0;
}
string 的读入和输出
string能用cin 读入,不能用scanf 读入 string可以用cout ,printf 输出
string 的常用操作
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "abc",s2 = "abcd";
cout << s1.empty() << endl;
cout << s1.size() << endl;
cout << s1>s2 << endl;
string s3 = s1+s2;
cout << s3 << endl;
return 0;
}
注意: 字面值和string对象相加: 做加法运算时,字面值和字符都会被转化成string对象,因此直接相加就是将这些字面值串联起来:
string s1 = “hello”, s2 = “world”; // 在s1和s2中都没有标点符号
string s3 = s1 + “, “ + s2 + ‘\n’;
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + ", "; // 正确:把一个string对象和有一个字面值相加
string s5 = "hello" +", "; // 错误:两个运算对象都不是string
string s6 = s1 + ", " + "world"; // 正确,每个加法运算都有一个运算符是string
string s7 = "hello"+ ", " + s2; // 错误:不能把字面值直接相加,运算是从左到右进行的
substr() 取出字串的函数: s.substr(p, len) 返回一个string,包含s中从p开始的len个字符的拷贝(pos的默认值是0,n的默认值是s.size() - len,即不加参数会默认拷贝整个s) 另外,若len的值超过了string的大小,则substr函数会抛出一个out_of_range异常;若pos+n的值超过了string的大小,则substr会调整n的值,只拷贝到string的末尾
遍历处理string对象
可以将string对象当成字符数组来处理
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1 = "Hello World";
for(int i =0;i<s1.size();i++) cout << s1[i] << endl;
for(char c: s1) cout << c << endl;
for(char &c:s1) c='0';
cout << s1 << endl;
return 0;
}
stringstream 把字符串初始化为一个类似于cin的方式,从中读出需要的信息
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string s;
getline(cin,s);
int a,b;
double c;
string str;
stringstream ssin(s);
ssin >> a >> b >> str >> c ;
cout << a << endl << b << endl << str << endl << c << endl;
return 0;
}
练习题: Acwing 770 单词替换 Acwing 771 字符串中最长的连续出现的字符 Acwing 777 字符串的乘方 Acwing 778 字符串最大跨距 Acwing 779 最长公共字符串后缀
|