回 帖 发 新 帖 刷新版面

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

第一题:
1楼、Mato_完整版,结果错误
4楼、rickone,结果正确
5楼、zhangc511, N * 1时错误
7楼、abc123,结果正确
10楼、ww2734,不符合要求
13楼、ati9200pro,结果正确
14楼、shbgreenery,结果正确
15楼、yuwg_le, h != w时错误
16楼、rongyuanhua,编译不过
17楼、hdzhyf,程序存在越界写错误,程序执行异常
18楼、ppc,结果正确
19楼、boxertony,结果正确


rickone,结果正确
abc123,结果正确
ati9200pro,结果正确
shbgreenery,结果正确
ppc,结果正确
boxertony,结果正确


第二题:
在文件行数较少情况下:
3楼、Mato_完整版,不符合要求
rickone,未实现
zhangc5,未实现
9楼、abc123,结果正确
ww2734,未实现
13楼、ati9200pro,结果正确
shbgreenery,未实现
yuwg_le,未实现
rongyuanhua,未实现
17楼、hdzhyf 结果正确
ppc,未实现
19楼、boxertony,结果正确
        
abc123,结果正确
ati9200pro,结果正确
hdzhyf,结果正确
boxertony,结果正确

同时作对两题的有
abc123
ati9200pro
boxertony

比较速度
每行4个字符,内容随机
取文件1固定10000行,
文件2 的行数递增从1 开始以10倍递增

file2 line = 1
abc123 0.031 sec
ati9200pro 2.422 sec
boxertony 0.016 sec

file2 line = 10
abc123 0.062 sec
ati9200pro 4.750 sec
boxertony 0.032 sec

file2 line = 100
abc123 0.140 sec
ati9200pro 7.313 sec
boxertony 0.032 sec

file2 line = 1000
abc123 0.734 sec
ati9200pro 9.875 sec
boxertony 0.048 sec

file2 line = 10000
abc123 6.720 sec
ati9200pro //超时
boxertony 0.061 sec

file2 line = 100000
abc123 //超时
boxertony 0.139 sec

file2 line = 1000000
boxertony 0.688 sec

file2 line = 10000000
boxertony 6.000 sec

file2 line = 100000000
boxertony //超时


实际上第二题完全按题目要求实现的一个都没有!这个完全出乎我的意料。。。。。。。。。。。。。
所有把一个或两个文件全部内容读进内存的均不符合要求,
ati9200pro使用硬盘过渡也不符合我的设想。

最终决定选速度相对快的boxertony为冠军,下次比赛请boxertony主持。

有异议尽管提!!!

回复列表 (共16个回复)

沙发

出乎意料
我一直认为我是冠军的。。。

下次比赛快些吧
我一定要搞个冠军出来!

郁闷。。。

boxertony的代码我要研究下, 第2题竟然比我快, 不可思议

板凳

我觉得地2题题意没说清楚

其实C更快吧, 我只是图结构方便猜用的C++

开来题目2用C是快的

但是比起结构和修改的角度C++还是好的 

既然是速度战, 还是C好啊

今后比赛用C好了

3 楼

哈, boxertony的CHAR是我的STRING
FILE是我的FSTREAM

怪不得慢的要死
思路差不多

4 楼

[quote]出乎意料
我一直认为我是冠军的。。。

下次比赛快些吧
我一定要搞个冠军出来!

郁闷。。。

boxertony的代码我要研究下, 第一题竟然比我快, 不可思议[/quote]
不是第一题,而是第二题。
而且这个与使用的语言无关,关键第二题使用的算法是什么,你可以自行测试比较。

5 楼


这个题难乎?易乎?我都糊涂了。
TO:abc123!!! 难得都没睡,你可以测试一下,两个文件的行数均超过百万行时
   abc123
   ati9200pro
   boxertony三者均会出现什么情况。
   
   下面给出我的程序,程序还有点小问题,懒的优化了。
   
   取每行字符个数为随机x%80, 
   文件1 固定取行数为1000000行,
   
   当文件2 行数为1000000行时用时34秒
   当文件2 行数为10000000行时用时263秒
   
   
   unsigned int strHash(char *str)
{
    unsigned int hash = 5381 ;
    
    while ( * str)
    {
        hash += (hash << 5 ) + ( * str ++ );
    }
    return (hash & 0x7FFFFFFF );
}

typedef struct tagHashInfo
{
    long lLinePos;
    tagHashInfo * pNextNode;
}hashInfo;

long getFileLen(FILE *fp2check)

    long lFilelen = 0;
    long lCurPos = ftell(fp2check);
    fseek(fp2check, 0L, SEEK_END);
    lFilelen = ftell(fp2check);
    fseek(fp2check, lCurPos, SEEK_SET);
    return lFilelen;
}

int findDuplicateLine(const char *pszFile1,    const char *pszFile2, const char *pszFileOut)
{
    FILE *fp1 = NULL;
    FILE *fp2 = NULL;
    FILE *fpOut = NULL;
    
    if(NULL == (fpOut = fopen(pszFileOut, "w")))
    {
        return -1;
    }
    if(NULL == (fp1=fopen(pszFile1, "r")))
    {
        fclose(fpOut);
        return -1;
    }
    if(NULL == (fp2=fopen(pszFile2, "r")))
    {
        fclose(fpOut);
        fclose(fp1);
        return -1;
    }
    
    FILE * fpFragmentHash = fp1;
    FILE * fpForEach = fp2;
    long lLen1 = getFileLen(fp1);
    printf("lLen1 = %ld\n", lLen1);
    
    long lLen2 = getFileLen(fp2);
    printf("lLen2 = %ld\n", lLen2);
    long lMinFileLen = lLen1;
    if (lLen2 < lLen1)
    {
        fpFragmentHash = fp2;
        fpForEach = fp1;
        lMinFileLen = lLen2;
    }
    
#define FRAGMENT_MAX 8000000
    //文件行数最多等于文件字节数
    //也可以去历遍文件去计算得到那个文件行数最少
    if (FRAGMENT_MAX < lMinFileLen)
    {
        lMinFileLen = FRAGMENT_MAX;
    }
    hashInfo **ppHashTable = (hashInfo **)malloc(sizeof(hashInfo*) * lMinFileLen); 
    
    printf("lMinFileLen = %ld\n", lMinFileLen);
    
    if(NULL == ppHashTable)
    {
        printf("XXXXXXXXXXXXXXXXXXXXXX out of memory !!\n");
        fclose(fpOut);
        fclose(fp1);
        fclose(fp2);
        return -1;
    }
    
#define MAX_LINE_LENGTH 83
    unsigned long ulDuplicateLines = 0;
    char szLine1[MAX_LINE_LENGTH] = {'\0'};
    char szLine2[MAX_LINE_LENGTH] = {'\0'};
    unsigned int uIndex = 0;
    hashInfo *pHashInfo = NULL;
    
    while(!feof(fpFragmentHash))
    {
        memset(ppHashTable, 0x00, sizeof(hashInfo*) * lMinFileLen);
        for (unsigned long u = 0; u < lMinFileLen; u++)
        {
            long lLineHeadPos = ftell(fpFragmentHash);
            
            fgets(szLine1, MAX_LINE_LENGTH, fpFragmentHash);
            
            uIndex = strHash(szLine1) % lMinFileLen;
            pHashInfo = ppHashTable[uIndex];
            
            if (NULL == pHashInfo)
            {
                ppHashTable[uIndex] = (hashInfo*)malloc(sizeof(hashInfo));
                ppHashTable[uIndex]->lLinePos = lLineHeadPos;
                ppHashTable[uIndex]->pNextNode = NULL;
            }
            else
            {
        hashInfo *pFirst = pHashInfo->pNextNode;
        ppHashTable[uIndex] = (hashInfo*)malloc(sizeof(hashInfo));
        ppHashTable[uIndex]->lLinePos = lLineHeadPos;
        ppHashTable[uIndex]->pNextNode = pFirst;
            }
            
            if (feof(fpFragmentHash))
            {
                break;
            }
        }
        
        

6 楼

//printf("======================================================\n");
        
        long lFileFragmentPos = ftell(fpFragmentHash);
        while(!feof(fpForEach))
        {
            fgets(szLine2, MAX_LINE_LENGTH, fpForEach);
            uIndex = strHash(szLine2) % lMinFileLen;
            pHashInfo = ppHashTable[uIndex];
            if (NULL == pHashInfo)
            {
                continue;
            }
            
            while (NULL != pHashInfo)
            {
                fseek(fpFragmentHash, pHashInfo->lLinePos, SEEK_SET );
                fgets(szLine1, MAX_LINE_LENGTH, fpFragmentHash);
                
                if (0 == strcmp(szLine1, szLine2))
                {
                    fputs(szLine1, fpOut);
                    ulDuplicateLines++;
                }
                pHashInfo = pHashInfo->pNextNode;
            }
        }
        
        if (feof(fpFragmentHash))
        {
            break;
        }
        else
        {
            fseek(fpFragmentHash, lFileFragmentPos, SEEK_SET);
            rewind(fpForEach);
            for (unsigned long u = 0; u < lMinFileLen; u++)
            {
                pHashInfo = ppHashTable[u];
                if (NULL == pHashInfo)
                {
                    continue;
                }    
                while (NULL != pHashInfo)
                {
                   hashInfo *pNext = pHashInfo->pNextNode;
                   free(pHashInfo);
                   pHashInfo = pNext;
                 }        
            }
        }
    }
    fclose(fp1);
    fclose(fp2);
    fclose(fpOut);
    
    for (unsigned long u = 0; u < lMinFileLen; u++)
    {
        pHashInfo = ppHashTable[u];
        if (NULL == pHashInfo)
        {
            continue;
        }
        
        while (NULL != pHashInfo)
        {
            hashInfo *pNext = pHashInfo->pNextNode;
            free(pHashInfo);
            pHashInfo = pNext;
        }        
    }
    
    free(ppHashTable);
    return 0;
}

7 楼

《算法艺术与信息学竞赛》上说过一个好的字符串hash算法,用这个第二题可以达到O(N) (设N为字符串的个数)

8 楼

谢谢房主啦

我还是认为C++币 C慢。
不过你的负责让我钦佩, 谢谢房主

9 楼

哎,文件处理一直是我的弱项,看来还得学习啊。

第2题我好象走如歧路了,当时是考虑得太多,总想到内存有限,硬盘够大,没有从算法上去想解决这个问题的方法。不过若是将MAXLINES设大一点,在前面的表现可能会好很多,不过终究是落了下乘,继续学习ING。

10 楼

看来ati9200pro也和我从前一样, 文件操作一塌糊涂, 似懂非懂的。
虽然我现在会文件操作, 但每次都是拿着函数的索引。。。

一起加油吧!

对了!第一名跑到哪里去了?

我来回复

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