我正在解析数据集并为TStringList我想要避免重复项分配值.我使用以下代码但仍插入重复项.
channelList := TStringList.Create;
channelList.Duplicates := dupIgnore;
try
dataset.First;
while not dataset.EOF do
begin
channelList.Add(dataset.FieldByName('CHANNEL_INT').AsString) ;
dataset.Next;
end;
Run Code Online (Sandbox Code Playgroud)
为什么要添加重复项?
我有一个选择.
我有许多已经排序的字符串,我需要存储和访问.看起来我可以选择使用:
字符串的链接列表(单链接)
艾伦在他的评论中建议我也加入选择:
TList<string>在什么情况下,这些都比其他更好?
哪个最适合小清单(10项以下)?
哪个最适合大型列表(超过1000个项目)?
哪个最适合大型列表(超过1,000,000个项目)?
哪个最好最小化内存使用?
哪个最好最小化加载时间以在最后添加额外的项目?
哪个最好最小化从头到尾访问整个列表的访问时间?
在此基础上(或任何其他),哪种数据结构更可取?
作为参考,我使用的是Delphi 2009.
Dimitry在评论中说:
描述您的任务和数据访问模式,然后就可以给您一个确切的答案
好的.我有一个包含大量数据的家谱程序.
对于每个人,我有许多事件和属性.我将它们存储为短文本字符串,但每个人都有很多,范围从0到几百.我有成千上万的人.我不需要随机访问它们.我只需要将它们作为连接到每个人的已知顺序的多个字符串相关联.这是我的数千个"小名单"的案例.它们需要时间来加载和使用内存,如果我需要它们,则需要时间来访问(例如,导出整个生成的报告).
然后我有一些较大的列表,例如我的"虚拟"树视图的所有部分的名称,它们可以有数十万个名称.我再次只需要一个可以通过索引访问的列表.它们与树视图分开存储以提高效率,树视图仅在需要时检索它们.这需要一段时间来加载,并且对于我的程序来说,内存非常昂贵.但我不必担心访问时间,因为一次只能访问少数访问时间.
希望这能让您了解我正在努力实现的目标.
ps我在StackOverflow上发布了很多关于优化Delphi的问题.我的程序读取包含100,000人的25 MB文件,并在8秒内为它们创建数据结构和报告以及树视图,但使用175 MB的RAM来执行此操作.我正在努力减少这一点,因为我的目标是在32位Windows中加载数百万人的文件.
我刚刚在StackOverflow问题上找到了一些优化TList的优秀建议: 是否有更快的TList实现?
delphi linked-list tstringlist dynamic-arrays data-structures
我有一个.\input.txt像这样的文件:
aaa
bbb
ccc
Run Code Online (Sandbox Code Playgroud)
如果我使用读取并将其TStrings.LoadFromFile写回(即使不应用任何更改)TStrings.SaveToFile,则会在输出文件的末尾创建一个空行。
var
Lines : TStrings;
begin
Lines := TStringList.Create;
try
Lines.LoadFromFile('.\input.txt');
//...
Lines.SaveToFile('.\output.txt');
finally
Lines.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
使用该TStrings.Text属性可以观察到相同的行为,该属性将返回一个在其末尾包含空行的字符串。
我正在创建我的第一个自定义Delphi组件.它基本上是一个自定义的Tpanel,上面显示了标题和行文字.
我希望能够使用字符串列表添加多行文本.
测试组件时,添加行时无法在面板上显示文本行:NewLinesText.add('line1 text')
但是,当我在运行时创建并填充新的字符串列表然后将其分配给我的控件时,它确实有效:controlPanelitem.NewLinesText = MyNewStringlist
我希望能够添加如下行:NewLinesText.add('line1 text')
我在WinXP上使用Delphi 7专业版.见下面的代码.
任何帮助,将不胜感激!
unit ControlPanelItem;
interface
uses
SysUtils, Classes, Controls, ExtCtrls, Graphics, AdvPanel, StdCtrls,
Windows,Forms,Dialogs;
type
tControlPanelItem = class(TAdvPanel)
private
fLinesText : TStrings;
procedure SetLinesText(const Value: TStrings);
procedure SetText;
protected
public
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
published
property NewLinesText : TStrings read FLinesText write SetLinesText;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Samples', [tControlPanelItem]);
end;
constructor tControlPanelItem.Create(AOwner: TComponent);
begin
inherited;
fLinesText := TStringList.Create;
end;
destructor tControlPanelItem.Destroy;
begin
fLinesText.Free; …Run Code Online (Sandbox Code Playgroud) 我想在调试应用程序时显示TStringList的全部内容.相反,我只是得到指针.Flist仅显示地址.
我饶有兴趣地阅读了Nick Hodges关于你为什么要使用界面的博客 ,因为我已经爱上了我编码中更高层次的界面,所以我决定看看如何将它扩展到相当低的水平并调查支持因为这在VCL课程中存在.
我需要的一个常见构造是使用TStringList做一些简单的事情,例如这个代码将一个小文本文件列表加载到一个逗号文本字符串中:
var
MyList : TStrings;
sCommaText : string;
begin
MyList := TStringList.Create;
try
MyList.LoadFromFile( 'c:\temp\somefile.txt' );
sCommaText := MyList.CommaText;
// ... do something with sCommaText.....
finally
MyList.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
如果我可以使用MyList作为接口编写它似乎是一个很好的简化 - 它将摆脱try-finally并提高可读性:
var
MyList : IStrings;
//^^^^^^^
sCommaText : string;
begin
MyList := TStringList.Create;
MyList.LoadFromFile( 'c:\temp\somefile.txt' );
sCommaText := MyList.CommaText;
// ... do something with sCommaText.....
end;
Run Code Online (Sandbox Code Playgroud)
我看不到定义的IStrings - 当然不是在Classes.pas中,尽管在线编程时有关于它的引用.它存在吗?这是一个有效的简化吗?我正在使用Delphi XE2.
我经常发现我需要'调整'aa TStringList来准确保存N个元素,或者在列表中添加额外的空字符串,或者删除不必要的字符串.
在C++ STL容器上我可以使用该resize方法,但由于这似乎不存在,我通常会做这样的事情(警告:伪代码!).
list.beginUpdate;
while list.Count < requiredSize do
begin
list.add('');
end;
while list.Count > requiredSize do
begin
list.delete(list.count-1);
end;
list.endUpdate;
Run Code Online (Sandbox Code Playgroud)
是否有一种更为简单的方法可以忽略我做到这一点?
我有一个简单的字符串,由一些字符分隔,让我们说一个逗号.我应该能够创建一个TStringList并将其分隔符设置为逗号,然后将DelimitedText设置为我要解析的文本,并且应该自动解析它.
问题是,当我查看输出时,它还包含空格作为分隔符并填充我的结果.我怎样才能避免这种情况,或者有更好的方法来做到这一点.
我正在研究一个模拟程序.
程序所做的第一件事就是读取一个巨大的文件(28 mb,大约79'000行),解析每一行(大约150个字段),为对象创建一个类,并将其添加到TStringList.
它还会读入另一个文件,该文件在运行期间会添加更多对象.最后,它最终成为大约85,000个物体.
我正在使用Delphi 2007,程序使用了大量内存,但运行正常.我升级到Delphi XE,并将程序迁移过来,现在它使用了更多的内存,并且它在运行的一半时间内耗尽了内存.
所以在Delphi 2007中,它会在读取初始文件后最终使用1.4演出,这显然是一个巨大的数量,但在XE中,它最终使用了近1.8演出,这真的很大,导致耗尽并获得错误
所以我的问题是
谢谢
Delphi 2007中是否有任何集成解决方案来检查TStringList是否包含某个值的一部分?
例如:
List.AddObject('This is a string', customStringObject1);
List.AddObject('This is a mushroom', customStringObject2);
List.AddObject('Random stuff', customStringObject3);
Run Code Online (Sandbox Code Playgroud)
搜索"这是一个"应该给我"真实",因为前两个元素包含这个部分.
到目前为止我唯一知道的方法是TStringList.find(string,integer),但这会执行完整的字符串比较,即只搜索这是一个字符串将返回true.
有什么建议?
delphi ×10
tstringlist ×10
compare ×1
components ×1
debugging ×1
delphi-xe2 ×1
find ×1
interface ×1
linked-list ×1
parsing ×1