| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1099 人关注过本帖
标题:求一个简单的问题
只看楼主 加入收藏
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 10楼 TonyDeng
为什么我觉得从时间复杂度的角度分析这两个是一样的啊。
2012-02-18 12:24
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
時間差不了多少,但第一個版本的pch與pchEnd比較執行了兩次,第二個只有一次。第一個版本的行數短了,第二個版本多了一個if語句,代碼複雜度似乎大了一點。可能在某些人看來,會覺得第一個版本的代碼緊湊,或者不能容忍兩個return,但其實它不如第二個版本,清晰度是第二個版本的較好(比較而言,?:表達式的本質是if語句,把它還原了,就可以看到第一個版本其實有多複雜)。我主要的意思是,不要看代碼長短,效率不是那樣看的,未必代碼短、看起來簡潔,效率就會高。

事實上,這兩個版本都有潛在風險。我只是拿它們舉個例子罷了,指的是時間複雜度和空間複雜度。一般來說,時間效率高的代碼,往往代碼複雜度也是較高的,代碼量也大,即空間複雜度會大,也更難理解。把握平衡度很重要,不必過分追求。比如那個最簡短的八皇后問題的代碼,沒人能說它不精巧,但事實上沒幾個人能夠讀得懂和理解得了(在我看來,那是不可取的代碼,不過不排除有人追求這樣的代碼)。

[ 本帖最后由 TonyDeng 于 2012-2-18 13:00 编辑 ]

授人以渔,不授人以鱼。
2012-02-18 12:43
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
不妨看看遞歸吧。遞歸的代碼複雜度是很低的,非常簡潔,而且,函數調用只有一條指令,如果把函數調用的時間假設為與加法一樣的常數級別,那樣分析出來的時間複雜度就很不靠譜。對高級語言來說,很難根據源代碼判斷出形成的機器碼到底使用了多少指令的,一條C代碼指令與一條CPU指令很多時候不對等,除非我們非常熟悉編譯原理,很清楚每條C指令生成的機器碼是怎樣的,否則,單靠C代碼分析時間複雜度,沒多少意義。除了實際運行,沒有什麼辦法知道某個算法的真實效果,否則只能是想當然居多(即不能說沒有道理,但道理是有折扣的)。

最明顯的應該是vector標準容器和C動態數組的關係。按照C的慣常思維,事先給動態數組分配一定的空間,然後追加,效率是最高的,所以給vector做初始化時也應該事先給出一定的空間,但按照標準庫專家們的說法,其實效率最高的正確做法就是讓vector從空集合開始不斷push_back()添加元素,因為他們設計的方案就是這樣做才是最高效率的,而且這個容器的算法事實上比傳統C的數組算法快得多。但顯然無論是算法的實現代碼還是我們使用這個庫容器的代碼,也都較為複雜,甚至會覺得調用push_back()方法會有函數開銷,也覺得在循環中不斷求容器的size()尺寸會浪費時間而用一個變量把尺寸儲存起來,諸如此類的東西,其實似是而非。

我還是那句話,把精力耗費這些地方上面,屬於浪費。當然,個人愛好是沒什麼可指責的,喜歡就行,從中得到樂趣就行了。

授人以渔,不授人以鱼。
2012-02-18 13:43
czz5242199
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:4
帖 子:660
专家分:2400
注 册:2011-10-26
收藏
得分:0 
回复 13楼 TonyDeng
真心不赞同,当然,我没做过实际项目,目前接触的还只是一些偏向算法类的问题,而算法的时间复杂度分析是很重要的,从你的回答来看你应该不大了解时间复杂度的概念,比如
程序代码:
for (i=0; i<n; i++) p+=2;

for (i=0; i<n; i++)
{
    p=p+1;
    p=p+1;
}

这两个程序在学算法的认为是完全一样的,应该他们可比性不大,及时n达到了几十亿运算时间区别也不会太大,时间复杂度考虑的是指数级而非常数,就比如查找中顺序查找和二分查找复杂度分别为O(n)和O(log2(n)),这两个复杂度在n增大时运算时间会出现显著地差异,同时时间复杂度也是不考虑那些CPU的内部运算的。
2012-02-18 13:51
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你看看《算法導論》2.2節就行了。我不想跟算法派的人爭論這種問題。

在項目實踐中,都是在時間確實影響目標的情況下,才會考慮改進算法,如果不出現那種情形,是不會刻意設計的。現實是那種情況很少遇到,除非你非要往那個行業鑽,否則世界上絕大多數的企業項目,都很少需要這樣的東西。最需要的是什麼呢?比如從外部文件中把數據正確讀入、正確寫出,達到靈活增、刪、改的目的,這樣的編程慣用技能,就是有用的,而不是看你讀寫文件有多快,快慢那麼1秒2秒,沒多少人會在乎,但不能達到目的、弄錯了數據、丟失數據,那就是大事了。你看“我菜119”那個ListView的問題,需要算法嗎?不需要,但現實需要的往往就是解決那樣的問題,那本來應該在求學階段就掌握的。

授人以渔,不授人以鱼。
2012-02-18 14:08
beyondyf
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:103
帖 子:3282
专家分:12654
注 册:2008-1-21
收藏
得分:0 
Tony,你确实不懂什么是时间复杂度,还有空间复杂度。

劝你别再解释了。

重剑无锋,大巧不工
2012-02-18 14:13
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
回复 15楼 TonyDeng
你是台湾人吗?能不能用简体回帖?

我就是真命天子,顺我者生,逆我者死!
2012-02-18 14:33
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
回复 17楼 BlueGuy
好久不见了你了。。。

用心做一件事情就这么简单
2012-02-18 16:18
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
以下是引用TonyDeng在2012-2-18 11:29:44的发言:

關於複雜度,給你舉一個例子,看如下兩個版本的代碼:

 
void * memchr(void * pv, unsigned char ch, size_t size)
{
    unsigned char * pch = (unsigned char * )pv;
    unsigned char * pchEnd = pch + size;
    while (pch < pchEnd && *pch != ch) pch++;
    return ((pch < pchEnd) ? pch : NULL);
}


 
void * memchr(void * pv, unsigned char ch, size_t size)
{
    unsigned char * pch = (unsigned char * )pv;
    unsigned char * pchEnd = pch + size;
    while (pch < pchEnd)
    {
        if (*pch == ch) return (pch);
        pch++;
    }
    return (NULL);
}


你覺得哪個較好?
要我选是第二个,简洁明了。。。。

用心做一件事情就这么简单
2012-02-18 16:19
简约式迷恋
Rank: 2
等 级:论坛游民
帖 子:22
专家分:44
注 册:2012-1-19
收藏
得分:0 
LZ按最坏的情况算,也可以算平均值
2012-02-18 23:48
快速回复:求一个简单的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.017812 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved