zoukankan      html  css  js  c++  java
  • 对代码风格的探索(持续更新)


    前言

    学习了下这个人的风格

    这篇博文主要记录一下我对自己代码风格的改善。

    代码风格的改善一般还是为了休闲, 但有时其带来的收益确实是巨大的,

    我个人认为绝大多数情况下收益体现在常数、编码难度和代码阅读舒适度上。


    基本 style

    if-else语句和三目运算符

    基本

    参考 这篇文章, 两者的效率似乎没有差别;参考 这篇文章, 得知上篇文章似乎默认编译器开启了优化。

    对于 if-else, 似乎有个叫做分支预测的东西使得这个语句要有上界为 14 的时钟周期, 而三目运算符只有 4。(这一句话是凭着模糊的记忆写出来的, 大可不看)

    即使 if-else 和三目运算符有着几乎相同的效率, 我还是喜欢使用三目运算符。

    要注意的是三目运算符似乎不能返回 void 类型, 所以在里面塞函数的时候要注意最后要加个 0。

    例如:这段代码可以正常运行, 输出结果是 4

    #include<bits/stdc++.h>
    using namespace std;
    
    void fuc1(int &x) {x += 1;}
    void fuc2(int &x) {x += 2;}
    
    int main() {
        int a = 1;
        // if(a==1) fuc1(a), fuc2(a);
        a==1 ? fuc1(a),fuc2(a),0 :0;
        cout << a;
        return 0;
    }
    

    实际上, 三目运算符可以在一定程度上代替 if-else 语句的本质是逗号表达式的性质, 参考自 这篇文章

    三目运算符不能代替如下 if语句:

    if(x) return;
    if(X) continue;
    if(P) break;
    

    其它的我就不知道了。

    一点小 trick

    短语句前置

    这个 trick 的意思是, 这样的一个分支:

    if(x) {
        o o o o
        o o o o
    } else o o;
    

    要改成三目运算符的话, !x ? o o : o o o o o o o o; 有时会比 x ? o o o o o o o o : x 写起来好看, 特别是分支有嵌套的时候。

    比如:

    int Merge(int a, int b)
    {
        return
        a&&b
        ?
            mx(a)<mx(b)?a^=b^=a^=b:0,
            rc(a) = Merge(rc(a),b),
            npl(lc(a))<npl(rc(a))
            ?
                lc(a)^=rc(a)^=lc(a)^=rc(a)
            :0,
            npl(a) = npl(rc(a))+1,
            a
        :a|b;
    }
    int Merge(int a, int b) {
    	return !a||!b ? a|b :
    		mx(a)<mx(b)?a^=b^=a^=b:0,
        	rc(a) = Merge(rc(a),b),
        	npl(lc(a))<npl(rc(a)) ? lc(a)^=rc(a)^=lc(a)^=rc(a):0,
        	npl(a) = npl(rc(a))+1,
        	a
    }
    

    当然, 实际上没啥卵用。


    尝试改善代码阅读体验

    1

    // 修改前
    #include<bits/stdc++.h>
    using namespace std;
    const int Mn = 2e5+3;
    
    int n,K;
    int ct, hd[Mn], nt[Mn*2+1], vr[Mn*2+1], w[Mn*2+1];
    void ad(int x, int y, int z) {nt[++ct]=hd[x], hd[x]=ct, vr[ct]=y, w[ct]=z;  }
    
    int d[Mn];
    long long dis[Mn];
    int T=1, f[21][Mn], ju[21][Mn];
    void dfs(int x, int fr) {f[0][x] = fr;
        for(int i=hd[x],y; i; i=nt[i]) (y=vr[i])!=fr ? d[y]=d[x]+1, dis[y]=0ll+dis[x]+w[i], dfs(y,x), 0 :0; }
    
    int fid(int x) {int y=x;for(int k=T;k>=0;--k) dis[x]-dis[f[k][y]]<K ?y=f[k][y] :0; return f[0][y];  }
    int lca(int x,int y) {
        d[x]>d[y] ? x^=y^=x^=y :0;
        for(int k=T;k>=0;--k) d[f[k][y]]>=d[x]?y=f[k][y]:0;
        if(x==y) return x;
        for(int k=T;k>=0;--k) f[k][y]!=f[k][x]? x=f[k][x],y=f[k][y] :0;
        return f[0][x];
    }
    
    int main() {
        scanf("%d%d",&n,&K); for(int i=1,x,y,z; i<n; ++i) {scanf("%d%d%d",&x,&y,&z), ad(x,y,z), ad(y,x,z);  }
        dfs(d[1]=1,0);
        while((1<<T)<n) ++T;
        for(int k=1;k<=T;++k)for(int i=1;i<=n;++i) f[k][i] = f[k-1][f[k-1][i]];
        for(int i=1;i<=n;++i) ju[0][i] = fid(i);
        for(int k=1;k<=T;++k)for(int i=1;i<=n;++i) ju[k][i] = ju[k-1][ju[k-1][i]];
        int q;scanf("%d",&q); for(int x,y,z; q; --q) {scanf("%d%d",&x,&y); z=lca(x,y);
            int ans = 0;
            for(int k=T;k>=0;--k) {
                d[ju[k][x]]>=d[z] ? x=ju[k][x], ans+=(1<<k) :0;
                d[ju[k][y]]>=d[z] ? y=ju[k][y], ans+=(1<<k) :0;
            }
            cout << ans+(dis[x]+dis[y]-2*dis[z]>=K) << '
    ';
        }
    return 0;}
    
    // 修改后
    #include<bits/stdc++.h>
    using namespace std;
    const int Mn = 2e5+3;
    
    int n,K;
    int ct, hd[Mn], nt[Mn*2+1], vr[Mn*2+1], w[Mn*2+1];
    void ad(int x, int y, int z)
    {nt[++ct]=hd[x], hd[x]=ct, vr[ct]=y, w[ct]=z;  }
    
    int d[Mn];
    long long dis[Mn];
    int T=1, f[21][Mn], ju[21][Mn];
    
    void dfs(int x, int fr)
    {f[0][x] = fr;
        for(int i=hd[x],y; i; i=nt[i]) (y=vr[i])!=fr ?d[y]=d[x]+1, dis[y]=0ll+dis[x]+w[i], dfs(y,x), 0 :0; }
    
    int fid(int x)
    {int y=x;for(int k=T;k>=0;--k) dis[x]-dis[f[k][y]]<K ?y=f[k][y] :0; return f[0][y];  }
    
    int lca(int x,int y)
    {
        d[x]>d[y] ? x^=y^=x^=y :0;
        for(int k=T;k>=0;--k) d[f[k][y]]>=d[x]?y=f[k][y]:0;
        if(x==y) return x;
        for(int k=T;k>=0;--k) f[k][y]!=f[k][x]? x=f[k][x],y=f[k][y] :0;
        return f[0][x];
    }
    
    int main()
    {
        scanf("%d%d",&n,&K);
        for(int i=1,x,y,z; i<n; ++i)
        	{scanf("%d%d%d",&x,&y,&z), ad(x,y,z), ad(y,x,z);  }
    
        dfs(d[1]=1,0);
    
        while((1<<T)<n) ++T;
        for(int k=1;k<=T;++k)for(int i=1;i<=n;++i) f[k][i]=f[k-1][f[k-1][i]];
        for(int i=1;i<=n;++i) ju[0][i] = fid(i);
        for(int k=1;k<=T;++k)for(int i=1;i<=n;++i) ju[k][i]=ju[k-1][ju[k-1][i]];
    
        	int q; scanf("%d",&q);
        	for(int x,y,z; q; --q)
        		{	scanf("%d%d",&x,&y); z=lca(x,y);
            		int ans = 0;
            			for(int k=T;k>=0;--k)
            			{d[ju[k][x]]>=d[z] ? x=ju[k][x], ans+=(1<<k) :0;
                			d[ju[k][y]]>=d[z] ? y=ju[k][y], ans+=(1<<k) :0; }
            			
            			cout << ans+(dis[x]+dis[y]-2*dis[z]>=K) << '
    ';
        		}
    return 0;}
    

    2

    // 修改前
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100003, M=300003;
    
    int re()
    {int x=0; char c=getchar(); while(!isdigit(c)){c=getchar();}
        while(isdigit(c)){x=x*10+c-'0', c=getchar();} return x;  }
    
    int n,m;
    
    struct iN{int x,y,s,e;  } b[M];
    bool cmp2(iN x, iN y) {return x.e>y.e; }
    
    int ct, hd[N], nt[M*2+1], vr[M*2+1], st[M*2+1], ed[M*2+1];
    void ad(int x, int y, int s, int e)
    { nt[++ct]=hd[x], hd[x]=ct; vr[ct]=y, st[ct]=s, ed[ct]=e;  }
    
    int q;
    struct nd{ int id, t; } a[N];
    bool cmp1(nd x, nd y) {return x.t<y.t; }
    
    int d1, ans[N];
    
    void dfs(int x, int t)
    {   if(x==1)
        { d1 = max(d1,t);
          return; }
         
        for(int i=hd[x]; i; i=nt[i]) {
            hd[x]=i;
            if(t<st[i]) return;
            dfs(vr[i],ed[i]);
        }
        hd[x] = 0;
    }
    
    int main() {
        n=re(), m=re();
        for(int i=1,x,y,s,e;i<=m;++i) b[i].x=re(),b[i].y=re(),b[i].s=re(),b[i].e=re();
        sort(b+1,b+1+m,cmp2);
        for(int i=1;i<=m;++i) ad(b[i].y,b[i].x,b[i].e,b[i].s);
        q=re();
        for(int i=1;i<=q;++i) a[i].t=re(), a[i].id=i;
        
        sort(a+1,a+q+1,cmp1);
        d1 = -1;
        for(int i=1;i<=q;++i) {
            dfs(n,a[i].t);
            ans[a[i].id] = d1;
        }
        
        for(int i=1;i<=q;++i) cout<< ans[i]<< '
    ';
        return 0;
    }
    
    //修改后
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100003, M=300003;
    
    int re()
    {int x=0; char c=getchar(); while(!isdigit(c))c=getchar();
        while(isdigit(c))x=x*10+c-'0',c=getchar(); return x; 
    }
    
    int n,m;
    
    struct iN{int x,y,s,e;  } b[M];
        bool cmp2(iN x, iN y) {return x.e>y.e; }
    
    int q;
    struct nd{ int id, t; } a[N];
        bool cmp1(nd x, nd y) {return x.t<y.t; }
    
    int ct, hd[N], nt[M*2+1], vr[M*2+1], st[M*2+1], ed[M*2+1];
    void ad(int x, int y, int s, int e)
    { nt[++ct]=hd[x], hd[x]=ct; vr[ct]=y, st[ct]=s, ed[ct]=e; 
    }
    
    
    int d1, ans[N];
    void dfs(int x, int t)
    {   if(x==1)
        { d1 = max(d1,t);
          return;
         }
         
        for(int i=hd[x]; i; i=nt[i])
        {   hd[x]=i;
            if(t<st[i]) return;
            dfs(vr[i],ed[i]);
        }
        hd[x] = 0;
    }
    
    int main() {
        n=re(), m=re();
        for(int i=1,x,y,s,e;i<=m;++i) b[i].x=re(),b[i].y=re(),b[i].s=re(),b[i].e=re();
        sort(b+1,b+1+m,cmp2);
        for(int i=1;i<=m;++i) ad(b[i].y,b[i].x,b[i].e,b[i].s);
        
        q=re();
        for(int i=1;i<=q;++i) a[i].t=re(), a[i].id=i;
        sort(a+1,a+q+1,cmp1);
        d1 = -1;
        for(int i=1;i<=q;++i)
        { dfs(n,a[i].t);
            ans[a[i].id] = d1;
        }
        
        for(int i=1;i<=q;++i) cout<< ans[i]<< '
    ';
        return 0;
    }
    
  • 相关阅读:
    练习jQuery
    Highcharts的应用步骤
    CSS中的数量查询
    何时使用 Em 与 Rem
    不错的教学网站
    HTML5中新增的语义化标签,及在IE5.5~9(IE9已经开始支持部分HTML5新标签了)支持这些新标签的兼容性处理。
    【洛谷P4139】上帝与集合的正确用法
    【洛谷P1357】花园
    【洛谷P1939】矩阵加速(数列)
    【洛谷P1962】斐波那契数列
  • 原文地址:https://www.cnblogs.com/tztqwq/p/13879886.html
Copyright © 2011-2022 走看看