前言
在打代码的很多时候,我们总会遇到很多等效但是时间效率却相差很大的语句,这对于一些大数据的程序优化起到了作用。我选择了几个自己经常遇到的做了一下总结。当然如果任何地方出现了任何错误,欢迎私信或评论指出。
First
我们首先看一段代码
for (i=0;i<=1000000;i++)
{
a[i]='.';
}
a[1000001]=0;
a[56]='a';
int ans=0;
for (int i=0;i<strlen(a);i++)
{
if (a[i]=='.') ans++;
}
我们要求的是点的数量,而这样子写的时间复杂度是很高的,问什么这么说呢?因为strlen本身是一个很慢的函数,它的时间复杂度是
的,所以我们应当用一个
来存储strlen(a)的值,这样子我们才做到真正的
。
所以我们在循环的时候尽量不要调用时间复杂度比较大的函数,在数据很大时可以大大优化。
Second
对于一个这样的程序
#include<cstdio>
const int N=1005
int a[N][N],b[N][N],c[N][N];
int main()
{
int ans=0;
for (int i=0;i<N;i++)
for (int j=0;j<N;j++)
for (int k=0;k<N;k++)
{
ans+=a[i][j]+b[i][k]+c[k][j];
}
}
我们运行大概要11秒才能结束。
但是当我们呢把
和
这两层交换的话,我们的时间就下降到了4秒多。首先我们证明
和
互换是不会影响正确性的,那么为什么可以优化这么多时间呢?
这是因为计算机中有一个磁盘,往上有一个主存,再往上有一个快速缓存,越往上总空间越小,但是越快。 我们进行这些操作是在主存,而数组什么的都在主存里。当程序需要调用一个数的时候,程序就会把它放到高速缓存里,然后来回这样穿。但是计算机有局部性,他会访问连续的空间。所以说,当我们把主存的东西放到高速缓存时,是把连续的一段放上去。这个二维数组存的时候转换成了一维,转的时候把一个个连续空间存起来。而原先的方法来回跳,就非常慢。当我们这么调换,就快多了。
所以在好几层循环的时候,我们要注意循环的顺序,让数组调用的时候连续一些。
Third
第三就是要讲一讲读入的问题。
有三种读入的方法:1)cin;2)cout;3)读入优化。他们的时间复杂度由前到后依次递减。所以我们在考虑范围的情况下,要选用正确的读入方式。(其实我并不是很推荐使用cin,太慢了)
关于读入优化,我们要采用函数getchar,因为这个函数很简单,每次就读入一个字符,所以复杂的不高。关于读入优化,代码如下:我不确定对不对
int getint()
{
char ch-getcahr();
while (ch<'0' || ch>'9') ch=getchar();
int res=0;
while ('0'<=ch && ch<='9')
{
res=res*10+ch-'0';
ch=getchar();
}
return res;
}//读入优化
后记
最后只总结到了这里……太菜了导致什么都不会