怎样将文本文件中的数字读到数组中。(100分)

  • 主题发起人 主题发起人 pwhll
  • 开始时间 开始时间
P

pwhll

Unregistered / Unconfirmed
GUEST, unregistred user!
一个文本文件,格式如下:
01 02 03 04 05
11 03 12 23 56
11 88 94 57 12
每个数字和数字之间为一空格,每一行有5个数字,一个文件有500行。
如何将每一个数字读到字节型数组中(一维,因每个数字都不大于255所有用字节型号数组),用最快最有效率的方法。

谢谢各位大侠了。
 
i:=0;
setlength(ByteArr,2500);
while not eof(f) do
begin
readln(f,s);
ByteArr[i*5]:=Byte(copy(s,1,2)); //转化可能不对
ByteArr[i*5+1]:=Byte(copy(s,4,2));
ByteArr[i*5+2]:=Byte(copy(s,7,2));
ByteArr[i*5+3]:=Byte(copy(s,10,2));
ByteArr[i*5+4]:=Byte(copy(s,13,2));
inc(i);
end;
//没有调试
 
Pascal 可以直接读取用空格分开的数据,15 年前就有的功能!跟“每一行有5个数字,一个文件有500行”压根没关系。
type
TByteData = array of Byte;
//FileName:文件名;Data:存储数据的动态数组
procedure GetTextData(const FileName: string; var Data: TByteData);
var
f: TextFile;
i: Integer;
begin
AssignFile(f, FileName);
FileMode := 0; //只读模式
Reset(f);
i := 0;
while not Eof(f) do
begin
Inc(i);
SetLength(Data, i);
Read(f, Data[i - 1]);
end;
CloseFile(f);
end;
 
这是我前几天写的一段代码,是把数据读取到StringList里面的。如果要读取到数组里面的话楼主你改一下吧。
procedure TForm1.Button1Click(Sender: TObject);
var
List: TStringList;
i: integer;
id, Date, time, a, temp, c: string;
begin
a := chr(32) + chr(32);
List := TStringList.Create;
try
od.Execute;
List.LoadFromFile(od.FileName); //读取TXT的数据
for i := 0 to List.Count -1 do //从0行开始循环
begin
id := copy(List, 0, pos(a, List) -1); //得到ID
temp := StringReplace(List, id + a, '', [rfReplaceALL]); //把ID外的数据取出来
date := copy(temp, 0, pos(a, temp)-1);
temp := StringReplace(temp, date + a, '', [rfReplaceALL]);
time := copy(temp, 0, pos(a, temp)-1);
temp := StringReplace(temp, time + a, '', [rfReplaceALL]);
c := c + id + chr(9) + date + chr(9) + time + chr(9) + temp + chr(13);
//这里写代码更新到你的数据库表中
end;
ShowMessage(c);
Finally
FreeAndNil(List);
end;
end;
 
TStringList下有两个属性Delimiter,DelimitedText,配合用一下就可以分开了,四五行代码就够了
 
谢谢各位的帮助,现在出现一新问题,我现在一个文本文件大约有110万行,一行有5个数字,这样,就需要定义一个[0..5500000] byte型的数组即550万个,可Delphi中一个数组最多能定义多少个元素呢?

现在我想换个思路,我读文本文件目的是求三个文件并集中每一行重复的个数并保存重复个数为1的数据,举列来说:

a.txt中有
01 02 03 04 05
02 03 04 05 06
11 23 44 45 76

b.txt中有
01 02 03 04 09
02 03 04 05 06
11 23 44 45 76

c.txt中有
01 02 03 04 09
02 03 04 05 06
11 23 44 45 88

则它们的并集为 重复次数
01 02 03 04 05 1
01 02 03 04 09 2
02 03 04 05 06 2
11 23 44 45 76 2
11 23 44 45 88 1

同样要求效率高一些,3个110万行的文件的处理时间能控制在5秒内。
我正在用Tstringlist来做,但太慢,即使排过序的Stringlist也很慢,让人不能接受,
目前考虑用clientDataset来做,谢谢大家的帮助,分可以再加。
处理不难,主要在速度上是一个难题,大家共同学习。再次谢谢各位。

vvyang大侠上个问题的解法很好,分已为你准备了,希望能帮助我解决这个问题。
谢谢!
 
在Delphi里面,数组的元素个数不能超过2GB也就是2*1024*1024*1024=2147483648个。所以550个元素的数组小菜一碟啦,另外从实际消耗存储空间看,550个字节元素的数组也只占用5M多一点的内存而已。
 
需不需要排序,和统计重复的次数?

问题并不是很复杂。
 
to:jeffrey_s
需要统计重复的次数,当然需要排序。

to:李奇
你不信定义一个[0..5500000]的byte型的数组试一下。看能不能应用,定义是能通过编译的,但是你要实例应用一下就会报溢出错误。
例如:定义为:a:array[0..5500000] of byte;
试着用一下:a[0]:=2;
 
堆栈溢出的解决方法有两个:
一、最简单的,把你的数组定义为全局变量,全局变量不在堆栈上分配,自然不存在堆栈大小限制的问题。
二、在项目选项里面调整堆栈大小限制--“Project->Options...->Linker->Memory Sizes->Max Stack Size”。这个Max Stack Size就是你的程序里面堆栈的最大尺寸限制,随便你调多大都行,只要你系统的可用内存足够。
 
110万行的文本要一个字节一个字节的解析到数字还要找出每行的重复数,
任何语言5秒内都是处理不了的.
就像拿一吨肉,问什么样的办法能让人一分钟吃完一样.
数据量在那里放着.太大了.
如果是数据库记录的话建好了索引的话可能会快上一点.
 
to:奇奇
谢谢你了。
这么说来,怎么才能解决这个问题。可以不用解析每一个数字,只需要检测每行的重复个数即可。
 
要解决你的问题不难,但想速度快是不大可能的了。根据你的文件结构:每行有5个数,每个数由两个数字字符组成,那么每行数字字符就占了10个字节,再加上每个数之间还有1个空格也就是说5个数要有4个空格,这样每个文本行的长度就是14个字节,最后还得加上文本行后面的换行回车也就是最终每行的长度会达到16个字节。
按照1个文件有110万行的规模,那么文件的大小就是1100000*16=17600000个字节,相当于16M多差不多17M,三个文本文件加起来就是51M左右。
要处理如此巨量的数据,无论你是用数据库还是字符串列表来筛选重复的文本行,速度都不可能达到只用3、5秒的水平。
 
算了。结贴吧,以后遇到此类问题,还是用数据库解决。
 
多人接受答案了。
 
用集合作就不需要排序吧一此就可以解决掉
 
后退
顶部