如何将分隔的 TStringlist 解析为整数的动态多维数组?

How to parse delimited TStringlist to dynamic multidimensional array of integer?

我一直在上下搜索 Delphi 函数或任何可以将 space 分隔的 TStringList(从 *.asc 文件加载)解析为动态二维整数数组的信息。

我有一个 ASCII 网格文件,其中包含网格格式的高程。首先,我将文件读入 TStringlist,将 header 数据提取到变量中,然后从 TStringlist 中删除 header 数据。我剩下的是一个 TStringlist,在 3601 x 3601 的网格中只有高程数据,每个值由 space 分隔。由于这个 Stringlist 仍在内存中,我想用海拔数据填充一个二维整数数组,然后释放 TStringList。

根据我的搜索,我偶然发现了一段代码 here 可以工作,但不完全。

我有的是:

var sourceData, tmpGrid, tmpRow : TStringList;
    val : String;
    Pos, i, j, k, l : Integer;
    nCols, nRows, noData : Integer;
    xllCorner, yllCorner, cellSize : Extended;
    Dem : array of array of Integer;
begin
 val := '';
 sourceData := TStringList.Create;
 tmpGrid := TStringList.Create;
 tmpRow := TStringList.Create;
 tmpRow.StrictDelimiter := True;
 tmpRow.Delimiter := ' ';
 sourceData.LoadFromFile('D:\ZA_DEM_DATA\Bulk_Order_466486\ARCASCII\s30_e026_1arc_v3.asc');

nCols := StrToInt(StripNonConforming(sourceData.Strings[0], ['0'..'9', '+', '-', '.']));
nRows := StrToInt(StripNonConforming(sourceData.Strings[1], ['0'..'9', '+', '-', '.']));
xllCorner := StrToFloat(StripNonConforming(sourceData.Strings[2], ['0'..'9', '+', '-', '.']));
yllCorner := StrToFloat(StripNonConforming(sourceData.Strings[3], ['0'..'9', '+', '-', '.']));
cellSize := StrToFloat(StripNonConforming(sourceData.Strings[4], ['0'..'9', '+', '-', '.']));
noData := StrToInt(StripNonConforming(sourceData.Strings[5], ['0'..'9', '+', '-', '.']));

Edit1.Text := IntToStr(nCols);
Edit2.Text := IntToStr(nRows);
Edit3.Text := FloatToStr(xllCorner);
Edit4.Text := FloatToStr(yllCorner);
Edit5.Text := FloatToStr(cellSize);
Edit6.Text := IntToStr(noData);

for I := 0 to 5 do
 begin
  sourceData.Delete(0);
 end;
//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;
SetLength(Dem, nCols, nRows);

Edit7.Text := IntToStr(sourceData.Count);

try
 for i := 0 to sourceData.Count -1 do
   for j := 0 to sourceData.Count -1 do
    begin
     Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
    end;
finally
 sourceData.Free;
end;

StringGrid1.ColCount := nCols;
StringGrid1.RowCount := nRows;
//This is mainly to visualise the data while testing the code
for i := 0 to nCols -1 do
  for j := 0 to nRows -1 do
   begin
    StringGrid1.Cells[i, j] := IntToStr(dem[i, j]);
   end;
 end;

我得到的结果是原始文件中显示的第一个 "row" 数据,但已复制到数组的所有行。例如:

原始数据:

1. 1245 1268 1232 1258
2. 1354 1321 1578 1689
3. 1461 1423 1475 1427
4. 1598 1541 1562 1550

我得到的是:

1. 1245 1268 1232 1258
2. 1245 1268 1232 1258
3. 1245 1268 1232 1258
4. 1245 1268 1232 1258

我们将不胜感激任何帮助。

这似乎是导致错误结果的原因

 for i := 0 to sourceData.Count -1 do
   for j := 0 to sourceData.Count -1 do
    begin
     Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
    end;

您已将实际数据从 SourceData 移动到不需要的 tmpGrid。相反,一次从 SourceData 分配一行到 tmpRow,然后一次从 tmpRow 读取一个值,并分配给值数组:

for i := 0 to SourceData.Count-1 do
begin
  tmpRow.DelimitedText := SourceData[i];
  for j := 0 to tmpRow.Count-1 do
    Dem[i,j] := StrToInt(tmpRow[j]);
end;

就在这行代码之后

//This is where I start parsing my TStrinList
tmpGrid.DelimitedText := sourceData.Text;

您的 sourceData 包含 4 行文本

1245 1268 1232 1258
1354 1321 1578 1689
1461 1423 1475 1427
1598 1541 1562 1550

tmpGrid包含16行文本

1245
1268
1232
1258
1354
1321
1578
1689
1461
1423
1475
1427
1598
1541
1562
1550

但您只能访问每行从 0 到 3 的 tmpGrid 行

 for i := 0 to sourceData.Count -1 do
   for j := 0 to sourceData.Count -1 do
    begin
     Dem[i][j] := StrToInt(tmpGrid.Strings[i]);
    end;

您应该更改代码以使用 nColsnRows 中的值,然后计算 tmpGrid

中的行
 for i := 0 to nCols -1 do
   for j := 0 to nRows -1 do
    begin
     Dem[i][j] := StrToInt(tmpGrid.Strings[i + j*nCols]);
    end;
i = 0 // first column
j = 1 // second row
i + j * nCols => 0 + 4 => fifth line of tmpGrid (zero indexed)