回 帖 发 新 帖 刷新版面

主题:第50次编程比赛结果

我首先谢谢大家的捧场和支持,重在参与,相信大家都很有收获。

第一轮先测试所有代码的正确性,筛走结果不正确的,有溢出现象的,不符合函数接口的,死循环的等等

后面的第二轮则是测试所以正确代码的运行速度。
丑媳妇总要见公婆,我的测试代码很简陋:(,请大家多多包涵

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

#define MAX_SIZE     ( 50 )
#define N            ( 5 )
#define TEST_COUNT   ( 1e6 )

typedef long long INT64;

void HeroNeedThree(INT64* subset, unsigned int n);

int main(int argc, char *argv[])
{
        INT64 subset[MAX_SIZE];
        clock_t start, end;
        int test_data[] = { 1, 1e3, 1e6, 2221+1, 4999999+1,
                            0x100000, 0x1000000, 0x10000000, 0xFFFFFFFF, 0 };
        int i, j, k;
        

        for (i = 0; test_data[i] > 0; ++i)
        {
                printf( "%d\t", i );
                for ( j = 0; j < N; ++j)
                {
                        start = clock();
                        for ( k = 0; k < TEST_COUNT; ++k )
                        {
                                HeroNeedThree( subset, test_data[i] );
                        }
                        end = clock();
                        printf( "%d\t", (int)(end - start) );
                }
                printf( "\n" );
        }
        system( "pause" );
        return 0;
}

下面是每个人的测试结果:

3楼 雨中飞燕
0       0       15      16      15      16
1       203     203     219     203     203
2       359     360     359     359     375
3       219     203     219     203     219
4       406     422     438     437     406
5       453     438     453     438     453
6       531     531     547     531     532
7       625     625     625     625     625
请按任意键继续. . .

8楼 renew
0       15      16      15      16      16
1       140     125     141     125     141
2       250     250     250     234     250
3       125     125     125     109     125
4       282     265     266     281     266
5       281     297     297     281     297
6       328     344     328     344     343
7       391     406     406     391     406
请按任意键继续. . .

12楼 poorb
0       15      31      16      16      31
1       531     531     516     516     531
2       1391    1375    1390    1391    1390
3       469     469     469     468     469
4       1485    1500    1484    1484    1485
5       1765    1750    1797    1735    1734
6       2609    2610    2625    2609    2625
7       3641    3672    3656    3640    3672
请按任意键继续. . .

15楼 euc
0       250     234     250     234     250
1       282     265     281     282     265
2       297     297     313     296     297
3       250     266     266     265     266
4       281     297     281     297     281
5       344     344     344     328     343
6       344     344     344     359     344
7       375     359     360     359     359
请按任意键继续. . .

16楼 ghbxx2004
0       31      15      32      15      16
1       234     219     234     204     218
2       391     375     391     375     390
3       203     219     203     203     203
4       438     422     422     437     406
5       500     500     485     515     485
6       594     578     593     579     593
7       672     688     672     687     688
请按任意键继续. . .

19楼 eastcowboy
0       31      31      31      32      15
1       219     219     218     204     234
2       391     390     406     391     391
3       203     203     203     203     203
4       438     437     438     422     437
5       500     485     484     500     484
6       578     579     562     578     578
7       672     672     672     672     656
请按任意键继续. . .

20楼 iAkiak
0       359     344     359     359     360
1       750     750     750     765     750
2       954     953     937     953     953
3       672     657     671     672     672
4       1016    1031    1016    1000    1031
5       1422    1422    1422    1437    1406
6       1610    1625    1625    1609    1609
7       1829    1812    1813    1828    1812
请按任意键继续. . .

21楼 rickone
0       125     140     141     125     125
1       234     203     203     204     218
2       250     250     250     250     266
3       187     188     187     203     188
4       265     250     235     265     266
5       281     297     281     282     281
6       297     312     313     297     297
7       313     312     313     312     313
请按任意键继续. . .

22楼 medie2005
0       218     203     204     187     203
1       563     562     578     563     562
2       1422    1406    1438    1406    1406
3       485     484     469     484     469
4       1484    1469    1485    1500    1468
5       2094    2109    2094    2094    2094
6       2937    2953    2953    2922    2938
7       3969    3953    3968    3938    3984
请按任意键继续. . .

24楼 Kummerwu
0       125     125     110     125     109
1       250     250     250     234     250
2       297     297     297     297     312
3       203     204     187     203     203
4       313     281     313     296     297
5       360     375     359     375     375
6       406     407     406     437     407
7       437     422     422     437     422
请按任意键继续. . .

26楼 xchbcahz
0       15      0       16      15      32
1       1609    1625    1609    1594    1610
2       4328    4359    4328    4328    4328
3       1141    1109    1125    1125    1125
4       4704    4703    4718    4704    4718
5       7719    7688    7718    7703    7750
6       11110   11062   11032   11062   11078
7       14985   14984   14953   14984   15016

29楼 wuchengwei
0       15      0       16      15      32
1       2047    2062    2047    2031    2047
2       3078    3078    3063    3078    3047
3       1656    1672    1672    1672    1672
4       3250    3250    3250    3250    3250
5       4890    4891    4890    4907    4906
6       5766    5781    5781    5797    5781
7       6688    6687    6688    6687    6703


34楼 forjane
0       125     125     109     125     125
1       203     203     203     203     204
2       265     250     266     265     266
3       188     171     172     188     172
4       234     250     266     250     250
5       297     296     297     297     297
6       297     312     313     312     313
7       312     313     312     313     312
请按任意键继续. . .

39楼 BigCarrot
0       16      15      32      15      16
1       219     203     219     203     203
2       375     375     375     375     375
3       219     203     218     204     218
4       422     422     438     421     422
5       453     469     453     453     438
6       531     531     547     532     531
7       625     609     625     610     625
请按任意键继续. . .

41楼 wangfangbob
0       215     216     215     200     232
1       340     325     341     325     341
2       434     403     419     419     418
3       310     309     325     309     325
4       466     434     435     434     435
5       512     497     497     497     497
6       559     559     560     543     560
7       606     606     622     606     607
请按任意键继续. . .

43楼 szh
0       15      0       16      15      16
1       344     328     344     343     344
2       641     640     641     625     625
3       281     282     281     265     282
4       687     688     703     672     687
5       1110    1109    1109    1110    1109
6       1438    1468    1469    1438    1468
7       1844    1828    1844    1828    1844
请按任意键继续. . .

45 楼天边蓝
0       125     125     140     110     140
1       2047    2063    2062    2047    2062
2       3032    3015    3032    3000    3031
3       1672    1656    1672    1656    1656
4       3219    3547    3234    3235    3218
5       4672    4672    4641    4656    4656
6       5516    5516    5531    5531    5516
7       6406    6406    6391    6406    6422
请按任意键继续. . .

比较突出的就是8楼,15楼,21楼 24楼 34楼
其中8楼不仅对大N速度很快,当N较小时效率也很快,并且位移的手法很巧妙,所以第50次编程比赛的冠军就是[color=FF0000][size=3]renew[/size][/color],大家祝贺一下他。
第51次编程比赛由renew来主持,请大家多多支持。

回复列表 (共33个回复)

11 楼

/********************************************************
*我把楼主的测试代码整合重测了一下,发现测试结果与楼主有很大的出入,
*是否是因为机器的不同导致的?
*下面是完整的测试代码,大伙可以拷贝到本地测试看看。
*

*感觉大数时15楼比较有优势,小数时8楼比较有优势
*而且测试数据中,大部分比特位都是0,正好比较适合8楼的口味:). [for (t = 0; m; m&=m-1) t++;循环次数比较少]
*所以测试结果比较好看.
*

*测试条件: VC6,Release版本(关闭系统的优化开关)
*           Win2k,SP4   CPU(2.6GHZ)
*测试结果:


8楼
0       16      16      0       15      16
1       78      125     94      94      93
2       203     188     187     204     203
3       109     109     94      109     110
4       218     204     234     203     219
5       203     219     234     203     219
6       266     265     266     250     266
7       297     281     265     282     281
8       297     297     297     297     296
请按任意键继续 . . .


15楼
0       219     218     235     218     235
1       250     234     250     250     235
2       265     266     266     281     265
3       219     235     218     250     235
4       266     266     265     235     281
5       250     266     250     265     266
6       250     250     266     265     250
7       235     265     250     250     282
8       265     250     266     250     266
请按任意键继续 . . .


21楼
0       125     140     141     141     140
1       250     235     234     266     250
2       344     343     328     329     343
3       250     235     265     250     250
4       329     343     344     344     344
5       422     406     422     422     406
6       438     453     453     422     437
7       484     500     500     485     500
8       532     562     610     531     562
请按任意键继续 . . .


24楼
0       188     219     250     203     187
1       203     219     234     250     203
2       250     266     281     266     234
3       219     188     203     203     187
4       266     250     250     250     250
5       297     266     297     281     297
6       265     297     297     266     281
7       297     297     281     297     281
8       297     313     297     281     281
请按任意键继续 . . .


34楼
0       204     187     219     187     204
1       281     297     297     281     266
2       375     375     359     375     375
3       266     234     266     250     265
4       375     391     406     375     391
5       421     422     438     437     454
6       484     500     500     484     501
7       562     563     578     562     563
8       547     547     578     547     562
请按任意键继续 . . .
************************************************************/

12 楼

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef __int64 INT64;
typedef __int64 BIGINT;


#define MAX_SIZE     ( 50 )
#define N            ( 5 )
#define TEST_COUNT   ( 1e6 )

static INT64 ThreePower[] = 
    {
        1,              3,              9,              27,
        81,             243,            729,            2187,
        6561,           19683,          59049,          177147,
        531441,         1594323,        4782969,        14348907,
        43046721,       129140163,      387420489,      1162261467,
        3486784401,     10460353203,    31381059609,    94143178827,
        282429536481,   847288609443,   2541865828329,  7625597484987,
        22876792454961, 68630377364883, 205891132094649,617673396283947,
    };


/////////////8楼////////////////////////////
void HeroNeedThree_8(BIGINT* subset, unsigned int n)
{
    int t, p;
    unsigned int m;
    m = n-1;
    for (t = 0; m; m&=m-1) t++;
    p = 0; m = n-1; subset[0] = t;
    while (t)
    {
        if (m & 1) subset[t--] = ThreePower[p];
        p++;
        m >>= 1;
    }
}
//////////////  15 楼/////////////////// 
void HeroNeedThree_15 (INT64* subset, unsigned int n)
{
    static INT64 three[41];
    static bool ini = false;

    if (ini == false) {
        INT64 a = 1;
        for (int i = 0; i < 41; ++i, a*=3) {
            three[i] = a;
        }
        ini = true;
    }

    int bitn = 31;
    unsigned int mask = (1 << 31);

    for (; bitn >= 0 && ((mask&n)==0); --bitn, mask >>= 1);

    int amount = 0;
    for (int i = 1; bitn >= 0; mask>>=1, --bitn) {
        if (n > mask) {
            subset[i] = three[bitn];
            amount++;
            n -= mask;
            i++;
        }
    }
    subset[0] = amount;
}


//////////////// 21 楼//////////////////////////////
void HeroNeedThree_21(INT64* subset, unsigned int n)
{
    // base3[k]=3^k
    static INT64 base3[32]=
    {
        0x1,0x3,0x9,0x1b,0x51,0xf3,0x2d9,0x88b,
        0x19a1,0x4ce3,0xe6a9,0x2b3fb,0x81bf1,0x1853d3,0x48fb79,0xdaf26b,
        0x290d741,0x7b285c3,0x17179149,0x4546b3db,0xcfd41b91,0x26f7c52b3,0x74e74f819,0x15eb5ee84b,
        0x41c21cb8e1,0xc546562aa3,0x24fd3027fe9,0x6ef79077fbb,0x14ce6b167f31,0x3e6b41437d93,0xbb41c3ca78b9,0x231c54b5f6a2b
    };
    // base2[k]=2^k
    static unsigned int base2[32]=
    {
        0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,
        0x100,0x200,0x400,0x800,0x1000,0x2000,0x4000,0x8000,
        0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000,0x800000,
        0x1000000,0x2000000,0x4000000,0x8000000,0x10000000,0x20000000,0x40000000,0x80000000
    };
    INT64 num=0;
    n--;
    for(int i=31;i>=0;--i)
    {
        if(n & base2[i]) // 计算n的第i位上是否是1
        {
            subset[++num]=base3[i];
        }
    }
    subset[0]=num;
}

13 楼


//////////// 24楼 /////////////////////////////////////////
void HeroNeedThree_24(INT64* subset, unsigned int n)
{
    static INT64 s_HelperCount[] = 
    {
        1,              3,              9,              27,
        81,             243,            729,            2187,
        6561,           19683,          59049,          177147,
        531441,         1594323,        4782969,        14348907,
        43046721,       129140163,      387420489,      1162261467,
        3486784401,     10460353203,    31381059609,    94143178827,
        282429536481,   847288609443,   2541865828329,  7625597484987,
        22876792454961, 68630377364883, 205891132094649,617673396283947,
    };


    int idx = 32;
    int cnt = 0;

    n--;
    while(idx>0)
    {
        idx--;
        if(((n)&(1<<(idx))))
        {
            cnt++;
            subset[cnt] = s_HelperCount[idx];
        }
        
        
    }
    subset[0] = cnt;
}

/////////////////////34 楼///////////////////////////////////////////
void HeroNeedThree_34(INT64* subset, unsigned int n)
{
    static INT64 powof3[32];
    static int initialized=0;
    int i;
    if(!initialized)
    {
        //你也可以在定义时直接初始化这个数组,如果你有耐心写一堆数字的话^_^
        for(i=1,powof3[0]=1;i<32;i++)
        {
            powof3[i]=powof3[i-1]*3;
        }
        initialized=1;
    }

    for(i=31,subset[0]=0,n--;i>=0;i--)
    {
        if(n&(1<<i)) //检查对应2进制位是否为1
        {
            subset[++subset[0]]=powof3[i];
        }
    }
}

//////////////////////////////////////////////////////
#define Test(FUNC,Info) \
do{\
    printf("\n\n%s\n",Info);\
for (i = 0; test_data[i] !=0; ++i)\
        {\
                printf( "%d\t", i );\
                for ( j = 0; j < N; ++j)\
                {\
                        start = clock();\
                        for ( k = 0; k < TEST_COUNT; ++k )\
                        {\
                                FUNC( subset, test_data[i] );\
                        }\
                        end = clock();\
                        printf( "%d\t", (int)(end - start) );\
                }\
                printf( "\n" );\
        }\
        system( "pause" );\
}while(0)


int main(int argc, char *argv[])
{
        INT64 subset[MAX_SIZE];
        clock_t start, end;
        int test_data[] = { 1, 1e3, 1e6, 2221+1, 4999999+1,
                            0x100000, 0x1000000, 0x10000000, 0xFFFFFFFF, 0 };
        int i, j, k;
        
        Test(HeroNeedThree_8,  "8楼");
        Test(HeroNeedThree_15, "15楼");
        Test(HeroNeedThree_21, "21楼");
        Test(HeroNeedThree_24, "24楼");
        Test(HeroNeedThree_34, "34楼");
        
        return 0;
}

14 楼

[quote][quote][quote]貌似少测试了一组... 0xffffffff[/quote]

int test_data[] = { 1, 1e3, 1e6, 2221+1, 4999999+1,
                            0x100000, 0x1000000, 0x10000000, 0xFFFFFFFF, 0 };

有啊[/quote]

嗯,判断条件写错了,没有测试0xFFFFFFFF[/quote]

呵呵 忘记了test_data有符号的 原先是!=0的,居然改错了,罪过 罪过

15 楼

没建表就是吃亏

16 楼

不但忘了定义成INT64,
还忘了考虑1的情况。
顶[em3]。

17 楼

我的建了表后会快很多,

冠军的代码若改成
void HeroNeedThree(INT64* subset, unsigned int n)
{
    int i,pos=31;

    for(--n, i=0; n; pos--)
    {
        if(n&(1<<pos))
        {
            subset[++i]=ThreePower[pos];
            n&=~(1<<pos);
        }
    }
    subset[0]=i;    
}
不知道会不会更快些

18 楼


wuchengwei的测试结果(Release 关闭优化开关)
0       15      16      15      16      16
1       593     579     593     579     578
2       765     782     750     781     797
3       578     594     562     563     562
4       844     844     860     843     829
5       844     875     891     859     860
6       968     969     969     1000    984
7       1079    1078    1078    1078    1032
8       1109    1094    1125    1125    1109
请按任意键继续 . . .

19 楼

我的上面测试的没超过400的

#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>

#define MAX_SIZE     ( 50 )
#define N            ( 5 )
#define TEST_COUNT   ( 1e6 )
typedef long long INT64;

INT64 ThreePower[32]={1};
void HeroNeedThree(INT64* subset, unsigned int n)
{
    int i,pos=31;

    for(--n, i=0; n; pos--)
    {
        if(n&(1<<pos))
        {
            subset[++i]=ThreePower[pos];
            n&=~(1<<pos);
        }
    }
    subset[0]=i;    
}

int main(int argc, char *argv[])
{
        INT64 subset[MAX_SIZE];
        clock_t start, end;
        int test_data[] = { 1, 1e3, 1e6, 2221+1, 4999999+1,
                            0x100000, 0x1000000, 0x10000000, 0xFFFFFFFF, 0 };
        int i, j, k;
        for(i=1; i<32;i++)
        {
                 ThreePower[i]=ThreePower[i-1]*3;
        }

        for (i = 0; test_data[i]; ++i)
        {
                printf( "%d\t", i );
                for ( j = 0; j < N; ++j)
                {
                        start = clock();
                        for ( k = 0; k < TEST_COUNT; ++k )
                        {
                                HeroNeedThree( subset, test_data[i] );
                        }
                        end = clock();
                        printf( "%d\t", (int)(end - start) );
                }
                printf( "\n" );
        }
        system( "pause" );
        return 0;
}

20 楼

[quote]我的上面测试的没超过400的[/quote]
呵呵,不好意思,代码拷贝错误。
wuchengwei
0       15      0       16      15      16
1       250     266     234     328     235
2       312     328     344     359     313
3       234     235     281     219     219
4       312     328     344     297     297
5       375     390     375     391     375
6       406     391     422     406     391
7       437     438     422     437     438
8       437     454     453     469     453
请按任意键继续 . . .
这时在我机器上的测试结果,因为机器不同,测试结果可能不同,与前面我测试时使用的是同一个环境,具有可比性

我来回复

您尚未登录,请登录后再回复。点此登录或注册