2015-04-02 20 views
0

我一直在尋找一個德爾福函數或任何可以解析空格分隔的TStringList(從* .asc文件加載)到整數的動態二維數組的信息。如何將分隔的TStringlist解析爲整數的動態多維數組?

我所擁有的是一個帶有網格格式高程的ASCII網格文件。首先我將文件讀入一個TStringlist,在這裏我將頭數據提取到變量,然後從TStringlist中刪除頭數據。我剩下的是一個TStringlist,它只有一個3601 x 3601的網格中的高程數據,每個值用一個空格分隔。有了這個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; 

結果我得到的是顯示在原始文件,但複製到陣列中的所有行數據的第一個「行」。例如:

原始數據:

 
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 

任何和所有幫助將不勝感激。

+1

好吧,看起來像'[debug-this-code-for-me]'應該是這裏的一個主要標籤。 – 2015-04-02 12:23:06

回答

2

這似乎是錯誤的結果

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; 
2

這個代碼行剛過

//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 tmpGrid線3的每一行

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) 
+0

感謝Rufo爵士,你的回答有幫助。起初我以爲有什麼事情導致了無盡的循環,因爲我的應用程序凍結了並保持了10分鐘以上。我決定再次測試一小塊數據,其大小的1/4確切無誤,而且似乎已經奏效。但是我的速度有問題花了1分09秒才完成900x900的測試數據。有沒有更快的方法可以嘗試探索,還是應該以不同的方式處理任務? – 2015-04-02 15:45:32

+0

@Martin您是否在速度測試中寫入了StringGrid?我發現你的定時報告令人難以置信,我做了一個測試(沒有StringGrid)並讀取一個900 x 900的值文本文件,將值轉換爲整數並分配給該數組需要大約一秒。我使用了我在我的答案中建議的方法,沒有tmpGrid StringList。 – 2015-04-02 18:34:02

+0

@湯姆,感謝您的評論,這讓我走上了正軌。顯然下面一行是「Memo1.Lines.Assign(tmpGrid);」是罪魁禍首。另外,只是一個附註,我首先遇到了一個問題,因爲它返回的「」不是有效的整數「錯誤,但是設法使用Trim修復它。謝謝你的幫助! – 2015-04-02 18:45:30