主题:第68次编程比赛结果
ckeryradish [专家分:140] 发布于 2008-07-11 23:12:00
第一题:
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个回复)
沙发
abc123!!! [专家分:1080] 发布于 2008-07-12 00:14:00
出乎意料
我一直认为我是冠军的。。。
下次比赛快些吧
我一定要搞个冠军出来!
郁闷。。。
boxertony的代码我要研究下, 第2题竟然比我快, 不可思议
板凳
abc123!!! [专家分:1080] 发布于 2008-07-12 00:18:00
我觉得地2题题意没说清楚
其实C更快吧, 我只是图结构方便猜用的C++
开来题目2用C是快的
但是比起结构和修改的角度C++还是好的
既然是速度战, 还是C好啊
今后比赛用C好了
3 楼
abc123!!! [专家分:1080] 发布于 2008-07-12 00:24:00
哈, boxertony的CHAR是我的STRING
FILE是我的FSTREAM
怪不得慢的要死
思路差不多
4 楼
ckeryradish [专家分:140] 发布于 2008-07-12 00:27:00
[quote]出乎意料
我一直认为我是冠军的。。。
下次比赛快些吧
我一定要搞个冠军出来!
郁闷。。。
boxertony的代码我要研究下, 第一题竟然比我快, 不可思议[/quote]
不是第一题,而是第二题。
而且这个与使用的语言无关,关键第二题使用的算法是什么,你可以自行测试比较。
5 楼
ckeryradish [专家分:140] 发布于 2008-07-12 01:06:00
这个题难乎?易乎?我都糊涂了。
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 楼
ckeryradish [专家分:140] 发布于 2008-07-12 01:07:00
//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 楼
卧龙孔明 [专家分:240] 发布于 2008-07-12 08:26:00
《算法艺术与信息学竞赛》上说过一个好的字符串hash算法,用这个第二题可以达到O(N) (设N为字符串的个数)
8 楼
abc123!!! [专家分:1080] 发布于 2008-07-12 10:04:00
谢谢房主啦
我还是认为C++币 C慢。
不过你的负责让我钦佩, 谢谢房主
9 楼
ati9200pro [专家分:100] 发布于 2008-07-12 11:41:00
哎,文件处理一直是我的弱项,看来还得学习啊。
第2题我好象走如歧路了,当时是考虑得太多,总想到内存有限,硬盘够大,没有从算法上去想解决这个问题的方法。不过若是将MAXLINES设大一点,在前面的表现可能会好很多,不过终究是落了下乘,继续学习ING。
10 楼
abc123!!! [专家分:1080] 发布于 2008-07-12 11:56:00
看来ati9200pro也和我从前一样, 文件操作一塌糊涂, 似懂非懂的。
虽然我现在会文件操作, 但每次都是拿着函数的索引。。。
一起加油吧!
对了!第一名跑到哪里去了?
我来回复