一些代码中的逻辑习惯
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一些代码中的逻辑习惯相关的知识,希望对你有一定的参考价值。
代码逻辑习惯或一些小操作(自己的笔记)
1.需要一个数组或者字符串的目前的元素和前一个元素做相关运算时:
直接遍历这个序列,当 i 等于0时不满足条件,只有i 等于 1时才会执行if语句
for(int i=0;i<len;++i)
{
if( i && 相关的运算) ...
}
2.与前一个元素做相关运算
我偏向定义一个变量pre代表前一个元素,然后从第二个位置开始遍历
感觉这样的代码确实有点多了,而且每次要更新pre的值
int pre = num[1];
for(int i=2;i<=n;i++)
{
相关的运算
pre = num[i];
}
3.存ASCII是否访问过,直接vis[200],开足够大的空间,ASCII本身也是一个数,直接用字符操作就行
vis[s[i]] ++;
4.判断一个序列是否是等差数列
遍历这个序列,将每个差分插入到一个集合中,如果最后集合的大小等于1,则为等差数列,还可以判断不同差分值的个数。
还可以通过set的方法访问首值和尾值
set<int>s;
int x = *s.begin();
int y = *s.rbegin();
5.在局部区域定义一个初始值为0的数组
int a[N]{};
可以发现最后a数组中的值都为0,和全局域定义的数组效果几乎一样。
vector数组第二维还可以赋值,将一个一维动态数组赋给一个二维数组的第二维
有一个定义数组的小技巧
//定义一个二维数组,第一维长度为200,第二维长度为0
vector<vector<int>> bk(200,vector<int>(0));
//m*n的二维vector,所有元素为0
vector<vector <int> > num(m ,vector<int>(n,0));
6.枚举二进制时的思路:一般数据范围比较小,需要枚举 0 ∽ 2 c n t − 1 0\\backsim2 ^{cnt}-1 0∽2cnt−1每个数,然后再对每个二进制位进行判断
for(int i=1;i<(1<<cnt);i++)//对每个数进行枚举
{
for(int j=0;j<cnt;j++)//对每个二进制位数进行判断
{
if(i&(1<<j))// i 代表这个数 1<<j是每个二进制位为1循环一遍,进行与运算,判断i的二进制位
{
}
}
7.定义vector用简单代码的输入,从0位置开始
vector<int> a(n);
for(auto &x : a){cin >> x;}
8.获得vector中的最大值(最小值)
max_element(v.begin(),v.end()) 返回的是最大值所在的迭代器,即位置
min_element(v.begin(),v.end()) 返回的是最大值所在的迭代器,即位置
vector<int >v;
int mx = *max_element(v.begin(),v.end());
int mn = *min_element(v.begin(),v.end());
9.c++结构体也可以写成员函数,通过打点来访问
struct node{
int cnt[N], ans = 0;
int add(int x)
{
......
}
}a[2];
10.卡空格写法
int f=1;
for(int i=1;i<=n;i++)
{
if(f)f=0; //如果为第一个元素,不输出空格,f置为0,接下来输出空格
else printf(" ");
}
11.求区间交集
有两个区间[a,b] [c,d],求区间交集长度
if(b<c||a>d) cout<<"无交集\\n";
else ll len = min(b,d)-max(a,c);
12.结构体也可以进行强制转化,真的是没想到
struct node
{
int x,y,z;
}a[105];//如果要添加构造函数的话,创建结构体数组就会出错,因为没有传入参数,无法调用构造函数
a[1] = (node){1,2,3};//将1,2,3强行转换为结构体类型,顺便还能赋值
13.前缀和还可以这样来求
for(int i=1;i<=n;i++)
{
a[i] += a[i-1];
}//直接用一个数组替代了两个数组
持续更新中… …
以上是关于一些代码中的逻辑习惯的主要内容,如果未能解决你的问题,请参考以下文章