关于我不知道是不是常数优化的【常数优化】

前言

在打代码的很多时候,我们总会遇到很多等效但是时间效率却相差很大的语句,这对于一些大数据的程序优化起到了作用。我选择了几个自己经常遇到的做了一下总结。当然如果任何地方出现了任何错误,欢迎私信或评论指出。

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本身是一个很慢的函数,它的时间复杂度是 O ( n ) 的,所以我们应当用一个 l 来存储strlen(a)的值,这样子我们才做到真正的 O ( n )
所以我们在循环的时候尽量不要调用时间复杂度比较大的函数,在数据很大时可以大大优化。

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秒才能结束。
但是当我们呢把 j k 这两层交换的话,我们的时间就下降到了4秒多。首先我们证明 j k 互换是不会影响正确性的,那么为什么可以优化这么多时间呢?
这是因为计算机中有一个磁盘,往上有一个主存,再往上有一个快速缓存,越往上总空间越小,但是越快。 我们进行这些操作是在主存,而数组什么的都在主存里。当程序需要调用一个数的时候,程序就会把它放到高速缓存里,然后来回这样穿。但是计算机有局部性,他会访问连续的空间。所以说,当我们把主存的东西放到高速缓存时,是把连续的一段放上去。这个二维数组存的时候转换成了一维,转的时候把一个个连续空间存起来。而原先的方法来回跳,就非常慢。当我们这么调换,就快多了。
所以在好几层循环的时候,我们要注意循环的顺序,让数组调用的时候连续一些。

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;
}//读入优化 

后记

最后只总结到了这里……太菜了导致什么都不会

猜你喜欢

转载自blog.csdn.net/gao_jue_yi/article/details/81086240
今日推荐