- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有这个代码
var
arr: TArray<string>;
e1, e2, e3, e4: string;
begin
e1 := 'val1';
e2 := 'val2';
e3 := 'val3';
e4 := 'val4';
arr := TArray<string>.Create(e1, e2, e3, e4);
我现在需要检查上面的数组中是否存在 e1 到 e4 两次,最好的方法是什么?我还应该跳过检查任何具有空值的元素。
另外请告知我是否应该手动释放这个数组
谢谢
最佳答案
为了玩算法的乐趣;如果原始数组足够大,可以使天真 O(n^2)
算法不切实际,并且由于 OP 使用的是具有泛型的 Delphi 版本,我建议使用 TDictionary<string, integer>
跟踪所有字符串而不排序,并识别重复项。
由于多种原因,这将是有效的:
O(n)
.我们从一开始就知道数组的大小,所以我们可以使用 TDictionary
从来没有种植过它。这使得整个算法 O(n)
.代码:
type
TZeroWidthRecord = record
end;
function FindFirstDuplicate(const ArrayOfString: array of string): Integer;
var Dict: TDictionary<string, TZeroWidthRecord>;
i: Integer;
ZW: TZeroWidthRecord;
begin
Dict := TDictionary<string, TZeroWidthRecord>.Create(Length(ArrayOfString));
try
for i:=0 to High(ArrayOfString) do
try
Dict.Add(ArrayOfString[i], ZW);
except on E:Exception do
Exit(i);
end;
finally Dict.Free;
end;
// No duplicates found:
Result := -1;
end;
为了回答 David 的评论,我制作了一个简短的测试程序来比较这个 TDictionary
基于算法到sort-and-search
算法。我创建了随机字符串数组,然后尝试找到第一个重复项。我的数组不包含重复项,如果有重复项,则 TDictionary 的运行时间将与平均首次命中重复项成正比。例如,如果平均而言 TDictionary 会在数组中间找到重复项,那么 TDict 算法的平均运行时间将为一半。基于排序的算法需要对整个数组进行排序,而排序是最耗时的。
与排序和基于字典的算法一样,需要使用真实 数据进行测试。例如,如果我在 OP 的问题中使用短字符串进行了测试,则 TDict 和排序之间不会存在竞争:即使对于微不足道的长度数组,Dict 也会更快。但是当平均字符串长度增加时,基于排序的算法开始变得更好;但话又说回来,这取决于字符串:例如,如果大多数字符串共享一个长前缀,那么排序算法中的“比较”阶段将花费更长的时间,从而再次使 TDictionary 看起来更好!
*==========*===========================*
| | Number of strings |
| Avg str | in the Array for |
| length | TDictionary to be faster |
*======================================*
| 7 | 33 |
| 10 | 73 |
| 13 | 73 |
| 16 | 163 |
| 19 | 163 |
| 22 | 366 |
| 25 | 366 |
| 28 | 549 |
| 37 | 2776 |
| 40 | 2776 |
| 43 | 2776 |
| 46 | 4164 |
| 49 | 9369 |
| 52 | 9369 |
| 55 | 9369 |
| 58 | 21079 |
*==========*===========================*
如果恰好在数组的中间找到第一个重复项,这将是结果。请注意平均字符串长度 58 的巨大差异:
*==========*===========================*
| | Number of strings |
| Avg str | in the Array for |
| length | TDictionary to be faster |
*======================================*
| 30 | 109 |
| 33 | 163 |
| 36 | 163 |
| 58 | 366 |
*==========*===========================*
如果在数组的 1/4 左右找到第一个重复项,就会发生这种情况:
*==========*===========================*
| | Number of strings |
| Avg str | in the Array for |
| length | TDictionary to be faster |
*======================================*
| 29 | 73 |
| 32 | 73 |
| 38 | 73 |
| 57 | 109 |
*==========*===========================*
这是测试应用程序:http://pastebin.com/vDznwKtZ
关于arrays - Delphi - 检查元素是否在 TArray<string> 中存在两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14524350/
在 C++ 中我可以做到 class A { public: A(std::vector> v) : _v(std::move(v)) {} private: std::vector>
我想知道以下代码是否会可靠地返回 nullptr 而不会出现任何复杂情况: TArray SomeActors; ASomeActor* SomeActor = SomeActors[0]; retu
我正在寻找一种更好的方法来初始化我的 lst_devices : TArray变量。 今天,我是这样做的(这非常丑陋,而且有代码味道,但至少可以正常工作)。 lst_devices_id := [''
uses Generics.Collections, types, rtti, System.Generics.Collections; procedure GimmePairArray(cons
这是什么原因TArray.Sort当我比较中有大量数字时不起作用? 我的代码如下(Delphiy Tokyo): Interface Type RCInd = record N
我刚刚开始接触这个。 PNode = ^TNode; TNode = record Obstacle : boolean; Visited : boolean; GCost : doubl
当我发现这样的构造实际上可以编译并产生所需的结果时,这只是偶然的: var Arr: TArray; begin Arr := TArray.Create(100, 101, 102); en
我有这个代码 var arr: TArray; e1, e2, e3, e4: string; begin e1 := 'val1'; e2 := 'val2'; e3 := 'val3'; e4 :
如何分配 TArray至array of Byte反之亦然? TEncoding.UTF8.GetBytes返回 TArray 。 TIdHashMessageDigest5.HashBytes有一个
我的代码的很大一部分( delphi-dutil 等)使用 TStringDynArray 。现在我想将所有键转换为 TDictionary到 TStringDynArray 。不幸的是我只找到了TD
在Delphi XE2的帮助中System.Generics.Collections.TArray.Sort ,它说 Note: If the Comparer parameter is provid
我知道 array of const被“翻译”为array of TVarRec由编译器所以我想知道是否有一种方法可以直接存储开放数组的副本(或者可能使用 const 的引用),我的意思是无需创建循环
虚幻引擎(C++) 您好,我有一个来自 TCP 连接的 TArray of Bytes。我有 58 字节的 header 和 12 x 4 字节的 Float32。我需要从我的 Array Bytes
这 3 种类型非常相似... TArray 是 TBytes 的通用版本。两者都可以转换为 PByteArray 并用作调用 Windows API 的缓冲区。 (与字符串到 Pchar 具有相同的限
我的记录类型定义如下: type TRecordType = record Field1: string; Field2: Variant; end;
我有很多变量声明为 var Something: array of XXX; begin SetLength(Something, 10); try ... finally
今天我发现了一个编译器错误 ( QC#108577 )。 以下程序无法编译: program Project1; {$APPTYPE CONSOLE} procedure P(M: TArray>);
我已将 outputBuffer 声明为 Byte 并相应地使用它: TFile.WriteAllBytes(outputPath, outputBuffer); 当我编译程序时,Delphi 输出:
我正在向在线 API 发出 GET 请求,但无法获取嵌套的 Json 值以设置为 C++(虚幻引擎 4)中的数组。我得到了除嵌套数组 LE (key) 之外的所有值 这里是 JSON {
我正在将旧版 Delphi 应用程序迁移到 Delphi-XE2,我想知道是否有充分的理由替换定义为 Array of MyType 的数组。至TArray 。那么问题来了 TArray 的优缺点是什
我是一名优秀的程序员,十分优秀!