我有3个列表,我会在这里简单说明。
字母列表
一个
乙
C
数字列表
1
2
3
混合
A,1个
A,2
B,2
B,3
C,1个
C,3
我需要知道缺少什么:
A,3
B,1个
C,2
信件清单有大约85个条目
并且数字列表有大约500个条目。
混合列表有大约75,000个条目。
我可以使用数据库查询(mysql 5.0)或Turbo Delphi 2006来处理文本文件。找到缺失的最佳方法是什么?
谢谢,
戴夫
答案 0 :(得分:3)
交叉连接会生成每个组合,因为您在SQL表中都有两个列表:
SELECT
Letter + ',' + Number AS Combination
FROM
NumberList,
LetterList
使用组合结果(可能将其保存到临时表中),您可以使用NOT EXISTS查询来查找缺少的内容:
SELECT
Combination
FROM
AllCombinations AS a
WHERE
NOT EXISTS
(SELECT 1 FROM MyCombitations AS m WHERE m.Combination = a.Combination)
这需要一个表MyCombitations
,它列出了您实际拥有的所有组合,并希望根据完整列表进行检查。
如果你想加快速度,你应该在MyCombitations.Combination
字段上使用永久的组合表和索引。对于重复查询,这绝对是可取的。
答案 1 :(得分:2)
无需创建额外的表格。以下查询也可以正常工作:
SELECT c.chr, n.num
FROM chars c, nums n
WHERE NOT EXISTS (SELECT 1
FROM mix m
WHERE m.chr = c.chr AND m.num = n.num)
答案 2 :(得分:1)
75.000并不多。将字母列表和数字列表加载到两个单独的TStringLists中。使用适当的维度创建动态数组(索引将是这两个字符串列表的索引)。填补;填写(表格,资料。加载数据并标记数组中的每一行。输出所有未标记的元素。
在伪代码中(未经测试):
var
i1, i2: integer;
sl1, sl2: TStringList;
cross: array of array of boolean;
begin
// load data into sl1, sl2
SetLength(cross, sl1.Count, sl2.Count);
for i1 := 0 to sl1.Count - 1 do
for i2 := 0 to sl2.Count - 1 do
cross[i1, i2] := false;
// for each element in 'combined' list
// split it into elements s1, s2
i1 := sl1.IndexOf(s1);
i2 := sl2.IndexOf(s2);
if (i1 < 0) or (i2 < 0) then
// report error
else
cross[i1, i2] := true;
for i1 := 0 to sl1.Count - 1 do
for i2 := 0 to sl2.Count - 1 do
if not cross[i1, i2] then
// output sl1[i1], sl2[i2]
end;
答案 3 :(得分:1)
SELECT letter,number FROM lettersTable l , numbersTable n WHERE
(
SELECT count(*)
FROM
(
SELECT *
FROM combinationsTable
WHERE l.letter=combinationsTable.letter AND n.number = combinationsTable .number
) AS temp
) = 0;
这依赖于SELECT * FROM A,B测试所有组合(隐式交叉连接)。
答案 4 :(得分:1)
如果你可以对数据进行排序(Turbo powers SysTools有一个很好的排序例程,那么你可以使用两个输入列表和一个输出列表在代码中相当快地完成此操作)。这背后的概念很简单:
这个过程有时被称为“老大师/新大师”过程,并且速度非常快,因为你只能在两个名单上行走一次。
简单示例:
var
ListL : tStringList; // the left list
ListR : tSTringList; // the right list
ListA : tSTringList; // the Add List (should start empty)
ListD : tStringList; // the Delete list (should start empty)
iCurL : integer; // Left Cursor
iCurR : integer; // Right Cursor
iRes : integer; // result of compare
begin
iCurL := 0;
iCurR := 0;
ListL := tStringList.create;
ListR := tSTringList.create;
ListA := tSTringList.create;
ListD := tStringList.create;
InitAndLoadLists(ListL,ListR,ListA,ListD);
while (iCurL <= ListL.Count-1) and (iCurR <= ListR.Count-1) do
begin
iRes := CompareStr(ListL.Strings[iCurL],ListR.Strings[iCurR]);
if iRes = 0 then
begin
inc(iCurL);
inc(iCurR);
end;
if iRes < 0 then
begin
ListA.Add(ListL.Strings[iCurL]);
inc(iCurL);
end;
if iRes > 0 then
begin
listD.Add(ListR.Strings[iCurR]);
inc(iCurR);
end;
end;
while (iCurL <= ListL.Count-1) do
begin
listA.Add(ListL.Strings[iCurL]);
inc(iCurL);
end;
while (iCurR <= ListR.Count-1) do
begin
listD.Add(ListR.Strings[iCurR]);
inc(iCurR);
end;
ShowMessage( 'ADDS' + ^M+^J + ListA.Text);
ShowMessage( 'DELS' + ^M+^J + ListD.Text);
end;
以下代码是我用于测试的代码。这只是一个例子,但在现实世界的情况下,我会构建我的密钥,以便他们可以正确排序,正确填充数字,并在适当的情况下强制执行。如果您使用的是turbo power sort例程,则可以使用两种类型而不是两个列表,但最终效果是相同的。
procedure InitAndLoadLists(ListL, ListR, ListA, ListD: TStringList);
begin
ListL.Add('A,1');
ListL.Add('B,3');
ListL.Add('C,2');
ListR.Add('A,2');
ListR.Add('B,3');
ListR.Add('C,4');
end;
编辑:在Delphi 2009中测试代码并且行为正常。