delphi字典迭代
g'morning!delphi字典迭代
我填充字典TDictionary<String, TStringlist>
(delphi-collections-unit),字符串作为值和几个字符串作为值。 类似:
- 名称=约翰,丽莎,斯坦
- 技能=读,写,说
- 年龄= 12,14,16
(没有 “” 当然, )。 我需要的是迭代这个字典,并用这些键乘以数值。 输出应该像
- 名称=约翰技能=读年龄= 12个
- 名称=约翰技能=读年龄= 14个
- 名称=约翰技能=读年龄= 16个
- 名称=约翰技能=写年龄= 12个
- 名称=约翰技能=写年龄= 14个
- 名称=约翰技能=写年龄= 16
- ...
- 名=丽莎技能=读年龄= 12
- ...
- 名=斯坦技能=说话的年龄= 16
所以每一个组合。 我该怎么做?键的数量是动态的,tstringlist的大小也是动态的。 谢谢!现在解决...
现在的问题与范围。以下是填写字典的程序。 subsplits和splitstring是字符串列表,在程序结束时被释放。该字典是在程序块(在main?它是如何调用的?)之后创建的,填充方法被调用,然后我想像代码示例中那样执行递归,但dict中没有值... 。
while not Eof(testfile) do
begin
ReadLn(testfile, text);
if AnsiContainsStr(text, '=') then
begin
Split('=', text, splitarray);
splitarray[0] := trim(splitarray[0]);
splitarray[1] := DeleteSpaces(splitarray[1]);
if AnsiStartsStr('data', splitarray[0]) then
begin
split(' ', splitarray[0], subsplit1);
splitarray[0]:=subsplit1[1];
split(',', splitarray[1], subsplit2);
dict.Add(splitarray[0], subsplit2);
for ValueName in dict.Values do
begin
for i := 0 to Valuename.Count - 1 do
write('Values are : '+ Valuename[i]);
writeln;
end;//
end;//
end;//
end;//
你想由位通过使用TDictionary<string, TStringList>
的复杂,因为这意味着变量的数字键的是什么。如果不是可变数目的键,则不需要字典,而只需迭代3个TStringLists。
这就是说,你有经典的“产生所有排列”问题。它可以使用递归或backtracking来解决。递归更容易实现,回溯使用更少的堆栈空间。这是你的选择。这是一个完整的控制台应用程序,完成整个交易,从初始化字典,填充字典,使用递归函数生成所有排列。
program Project23;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, Generics.Collections;
var
Dict:TDictionary<string, TStringList>;
L: TStringList;
KeyName: string;
KeysList: TStringList;
// Help procedure, adds a bunch of values to a "Key" in the dictionary
procedure QuickAddToDict(KeyName:string; values: array of string);
var L: TStringList;
s: string;
begin
// Try to get the TStringList from the dictionary. If we can't get it
// we'll create a new one and add it to the dictionary
if not Dict.TryGetValue(KeyName, L) then
begin
L := TStringList.Create;
Dict.Add(KeyName, L);
end;
// Iterate over the values array and add stuff to the TStringList
for s in values do
L.Add(s);
end;
// Recursive routine to handle one KEY in the dictionary
procedure HandleOneKey(KeyIndex:Integer; PrevKeys:string);
var L:TStringList;
i:Integer;
Part: string;
KeyName: string;
begin
KeyName := KeysList[KeyIndex];
L := Dict[KeyName];
for i:=0 to L.Count-1 do
begin
Part := KeyName + '=' + L[i];
if KeyIndex = (KeysList.Count-1) then
WriteLn(PrevKeys + ' ' + Part) // This is a solution, we're at the last key
else
HandleOneKey(KeyIndex+1, PrevKeys + ' ' + Part); // Not at the last key, recursive call for the next key
end;
end;
begin
try
Dict := TDictionary<string, TStringList>.Create;
try
// Add whatever you want to the Dict.
// Using the helper routine to set up the dictionary faster.
QuickAddToDict('names', ['john', 'lisa', 'stan']);
QuickAddToDict('skills', ['read', 'write', 'speak']);
QuickAddToDict('ages', ['12', '14', '16']);
// Extract all the keys to a string list. Unfortunately the dictionary
// doesn't offer a way to get a key name by index, so we have to use the
// keys iterator to extract all keys first.
KeysList := TStringList.Create;
try
for KeyName in Dict.Keys do
KeysList.Add(KeyName);
if KeysList.Count > 0 then
begin
// We got at least one key, we can start the recursive process.
HandleOneKey(0, '');
end;
finally KeysList.Free;
end;
WriteLn;
WriteLn('Press ENTER to make the window go away');
ReadLn;
finally
// TDictionary doesn't own the keys or the values. Strings are managed types in
// delphi, we don't need to worry about them, but we do need to free the TStringList's
// We use the Values iterator for that!
for L in Dict.Values do
L.Free;
Dict.Free;
end;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
完美的作品,谢谢! 3个for-loops非常清晰,是的。 – soulbrother 2011-04-07 08:48:36
由于这是你的第一个问题,如果你认为它解决了你的问题,并且是给出的最佳答案,请不要忘记接受答案。 – Runner 2011-04-07 08:49:33
该死的,是的。你的代码工作。但我的不是......我在程序中填写字典。我在我的内部试过你的代码。如果我重复proc中的值,他们是正确的。如果我在开始后这样做,这些值是错误的。代码是:parsefile是一个过程,填充了dict(全局变量)。但是离开程序时价值似乎会丢失......为什么? – soulbrother 2011-04-07 10:04:42
@stanislav,我编辑你的问题,使其可读性。下次,请自己动手。当你写下你的问题时,你的右边有一个帮助屏幕,解释了降价和底部的实时预览,这样你就可以知道你的问题一旦发布就会如何。 – 2011-04-07 07:47:29
你是对的。我也想编辑它,但你更快。谢谢! – soulbrother 2011-04-07 07:49:09
@stanislav,你的例子与你的问题不符。你不是在做“每一种组合”,你最后的例子是“lisa”,“read”和年龄“12”。如果这个例子是'names = stan,skills = speak,age = 16',那么解决方案很简单;现在,我不知道你想要什么! – 2011-04-07 07:50:07