彩票问题 如何将35选7中6724520种组合结果在10秒中之内写如数据库,文本也行(200分)

  • 主题发起人 1982ybsybs
  • 开始时间
DoubleWood的程序很快,我这里用了11秒.
赛扬 1.8,256 ddr,硬盘不详。
 
如何把hao[i1-1]附值给buf[curbyte-1],我实在想不出办法了
 
程序如下:
int a,b,c,d,e,f,g,i,j,k;
char str[35][2];
char ss[4096][15];
unsigned short hour1,hour,min,sec,msec,min1,sec1,msec1;
TDateTime t,t1;
t = t.CurrentTime();
FILE * out;
str[0][0]='0',str[0][1]='1',str[1][0]='0',str[1][1]='2';
str[2][0]='0',str[2][1]='3',str[3][0]='0',str[3][1]='4';
str[4][0]='0',str[4][1]='5',str[5][0]='0',str[5][1]='6';
str[6][0]='0',str[6][1]='7',str[7][0]='0',str[7][1]='8';
str[8][0]='0',str[8][1]='9',str[9][0]='1',str[9][1]='0';
str[10][0]='1',str[10][1]='1',str[11][0]='1',str[11][1]='2';
str[12][0]='1',str[12][1]='3',str[13][0]='1',str[13][1]='4';
str[14][0]='1',str[14][1]='5',str[15][0]='1',str[15][1]='6';
str[16][0]='1',str[16][1]='7',str[17][0]='1',str[17][1]='8';
str[18][0]='1',str[18][1]='9',str[19][0]='2',str[19][1]='0';
str[20][0]='2',str[20][1]='1',str[21][0]='2',str[21][1]='2';
str[22][0]='2',str[22][1]='3',str[23][0]='2',str[23][1]='4';
str[24][0]='2',str[24][1]='5',str[25][0]='2',str[25][1]='6';
str[26][0]='2',str[26][1]='7',str[27][0]='2',str[27][1]='8';
str[28][0]='2',str[28][1]='9',str[29][0]='3',str[29][1]='0';
str[30][0]='3',str[30][1]='1',str[31][0]='3',str[31][1]='2';
str[32][0]='3',str[32][1]='3',str[33][0]='3',str[33][1]='4';
str[34][0]='3',str[34][1]='5';
out = fopen("c://a.txt","w+");
i = 0;
for(a=35;a>0;a--)
{
for(b=a-1;b>0;b--)
{
for(c=b-1;c>0;c--)
{
for(d=c-1;d>0;d--)
{
for(e=d-1;e>0;e--)
{
for(f=e-1;f>0;f--)
{
for(g=f-1;g>0;g--)
{
ss[0] = str[a-1][0];
ss[1] = str[a-1][1];
ss[2] = str[b-1][0];
ss[3] = str[b-1][1];
ss[4] = str[c-1][0];
ss[5] = str[c-1][1];
ss[6] = str[d-1][0];
ss[7] = str[d-1][1];
ss[8] = str[e-1][0];
ss[9] = str[e-1][1];
ss[10] = str[f-1][0];
ss[11] = str[f-1][1];
ss[12] = str[g-1][0];
ss[13] = str[g-1][1];
ss[14] = '/n';
i ++;
if(i==4096)
{
fwrite(ss,15*4096,1,out);
i = 0;
}
}
}
}
}
}
}
}
fclose(out);
t1 = t1.CurrentTime();
t.DecodeTime(&hour,&min,&sec,&msec);
t1.DecodeTime(&hour1,&min1,&sec1,&msec1);
i = (hour1-hour)*60*60 + (min1-min)*60+(sec1-sec);
ShowMessage("共用时 " + AnsiString(i)+" 秒");
执行时间为:10-12秒,ce667
另外,每一次存一下盘好像比现在快,我没试。
顺便说一下你程序的错误:
1、hao定义的是每个元素为35个字符的指针。并且没有分配空间。buf是字符串,因此无法赋值。
2、delete buf错误,应为:delete [] buf;
 
最后试了一下,每次均存盘总用时4秒,到一定数量存盘总用时5-6秒。
机器:雷鸟1600+,256ddr。
 
时间主要消耗在写文件上了,把写文件去掉,只要1秒,写文件却需要41秒,惨不忍睹啊。
建议先缓存到内存中,再一次写入文件。
 
分配一个数量相当的内存,如用TMemoryStream,写入数据先全部写入内存,最后再写文件,频繁写一些小数量的数据到文件,速度是很慢的,你可以试一下。
 
TMemoryStream估计也不够快,直接用内存映射,一开始就分配一个 147M 的空间,
剩下的事情就是往里面写东西,最后关闭映射即可,估计会快些。
 
好像是可以达到10秒内,
我这里C4 1.7G, 512,大概在6-7秒之间。
void SetValue(char *Dst, char *Src, bool NextLine = false)
{
*Dst++ = *Src++;
*Dst++ = *Src++;
if (NextLine)
{
*Dst++ = '/r';
*Dst = '/n';
}
else
*Dst = 32;
}
void SaveToFile(const String FileName)
{
HANDLE hFile = CreateFile(FileName.c_str(), GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS, NULL);
if (hFile == NULL)
throw Exception(SysErrorMessage(GetLastError()));
try
{
unsigned CacheCount = 1024 * 1000;
char *Buffer = new char[CacheCount];
char *P = Buffer;
try
{
char *hao[35];
hao[0]="01", hao[1]="02", hao[2]="03", hao[3]="04",hao[4]="05",hao[5]="06",
hao[6]="07", hao[7]="08", hao[8]="09", hao[9]="10",hao[10]="11",hao[11]="12",
hao[12]="13", hao[13]="14", hao[14]="15",hao[15]="16",hao[16]="17",hao[17]="18",
hao[18]="19", hao[19]="20", hao[20]="21",hao[21]="22",hao[22]="23",hao[23]="24",
hao[24]="25", hao[25]="26", hao[26]="27",hao[27]="28",hao[28]="29",hao[29]="30",
hao[30]="31", hao[31]="32", hao[32]="33",hao[33]="34",hao[34]="35";
unsigned StreamLen = 0, LineLen = 7 * 2 + 6 + 2;
for(int i1 = 1;
i1 <= 29;
++i1)
{
for(int i2 = i1 + 1;
i2 <= 30;
i2++)
for(int i3 = i2 + 1;
i3 <= 31;
i3++)
for(int i4 = i3 + 1;
i4 <= 32;
i4++)
for(int i5 = i4 + 1;
i5 <= 33;
i5++)
for(int i6 = i5 + 1;
i6 <= 34;
i6++)
for(int i7 = i6 + 1;
i7 <= 35;
i7++)
{
StreamLen += LineLen;
if (StreamLen >= CacheCount)
{
unsigned long BytesWriten = 0;
WriteFile(hFile, Buffer, StreamLen - LineLen,
&amp;BytesWriten, NULL);
if (BytesWriten != StreamLen - LineLen)
throw Exception(SysErrorMessage(GetLastError()));
StreamLen = LineLen;
P = Buffer;
}
SetValue(P, hao[i1-1]);
P += 3;
SetValue(P, hao[i2-1]);
P += 3;
SetValue(P, hao[i3-1]);
P += 3;
SetValue(P, hao[i4-1]);
P += 3;
SetValue(P, hao[i5-1]);
P += 3;
SetValue(P, hao[i6-1]);
P += 3;
SetValue(P, hao[i7-1], true);
P += 4;
}
}
unsigned long BytesWriten = 0;
WriteFile(hFile, Buffer, StreamLen, &amp;BytesWriten, NULL);
if (BytesWriten != StreamLen)
throw Exception(SysErrorMessage(GetLastError()));
}
__finally
{
delete []Buffer;
}
}
__finally
{
CloseHandle(hFile);
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned Start = GetTickCount();
SaveToFile("D://temp.txt");
Caption = GetTickCount() - Start;
}
 
从另外一个角度去思考问题:
因为瓶颈是磁盘操作,所以你可以想办法缩小数据量,1~9加上26个英文字母刚好是35,
那么可以用A~Z来代替10~35,这样就可以节省一半的空间,响应的,计算的速度也可以加
快。速度提高一倍不是问题,呵呵。
 
我现在的速度是3.41秒(最快的时候)
电脑配置是:cr1.7,256ddr内存,硬盘转数不详,我感觉和硬盘转数有很大关系
 
验证了一下我的想法,结果是1秒左右
var
a,b,c,d,e,f,g: Integer;
i: integer;
tick: cardinal;
fi: file of byte;
table: array [1..35] of Char;
Buffer: array [0..65535] of char;
BufCount: Integer;
begin
assignfile(fi,'c:/test.txt');
Rewrite(fi);
tick := gettickcount;
for i:= 1 to 9do
table := chr(Ord('0')+i);
for i:= 0 to 25do
table[i+10] := chr(Ord('A')+i);
i := 0;
BufCount := 0;
for a := 1 to 29do
begin
for b := a+1 to 30do
begin
for c:= b+1 to 31do
begin
for d:= c+1 to 32do
begin
for e:= d+1 to 33do
begin
for f:= e+1 to 34do
begin
for g:= f+1 to 35do
begin
Buffer[BufCount] := table[a];
Buffer[BufCount+1] := table;
Buffer[BufCount+2] := table[c];
Buffer[BufCount+3] := table[d];
Buffer[BufCount+4] := table[e];
Buffer[BufCount+5] := table[f];
Buffer[BufCount+6] := table[g];
Buffer[BufCount+7] := #13;
Buffer[BufCount+8] := #10;
Inc(BufCount, 9);
if (BufCount+9)>65536 then
begin
BlockWrite(fi,Buffer[0],BufCount);
BufCount := 0;
end;
inc(i);
end;
end;
end;
end;
end;
end;
end;
BlockWrite(fi,Buffer[0],BufCount);
Closefile(fi);
caption := inttostr(i);
caption := caption+'|'+inttostr(gettickcount-tick);
end;
 
DoubleWood:
我试了一下,结果不对,都是乱码。
 
程序已经修改,请再试,呵呵
 
不用delphi,用VB,或C++行不行??
 
DoubleWood:
还不对
 
不可能啊,我测试是正确的,不过用A~Z来代替10~35而已啊
 
别忙给分,等我试试。可能行。
 
很欣赏DoubleWood的解法。
这不光是程序,更是创意。
 
我有一個思路, 但沒時間試, 先將數據生成到內存中, 再在內存中壓縮, 然后再保存,
讀入時相反.
 
既然这6724520种组合结果是固定的。
你可以把它们事先存入一个文件,需要时再从文件中读取呀。
何必每次都去产生。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部