k804138
一般會員
發表:3 回覆:4 積分:1 註冊:2005-04-04
發送簡訊給我
|
FILE *fp4,*fin4,*fcin4;
int finish_line;//要做的點數 以下面的例子finish_line=4
typedef struct relnode
{
int s0,s1;
float s2;
}relation;
relation temp,refer;
fin4=fopen("D:\\grey\\in.txt","r");
fp4=fopen("D:\\grey\\out.txt","w");
int cal_add_num=(finish_line-1)*finish_line;
for(int i=0;i 其中in.txt裡的資料如下:
0 1 0.793944
0 2 0.665598
0 3 0.698406
1 0 0.782290
1 2 0.755885
1 3 0.664225
2 0 0.650014
2 1 0.764225
2 3 0.924070
3 0 0.677153
3 1 0.663666
3 2 0.886344 refer與temp讀取同一個檔,其中先讀取一次refer,然後在讀取temp(連續讀取),當refer與temp的s0跟s1顛倒相同的時候,將他們的s2將相加然後寫入fp4. 寫完的out.txt為:
0 1 1.576234
0 2 1.315612
0 3 1.375559
1 2 1.520110
1 3 1.327891
2 3 1.810414 但是再執行這一段程式所需要的時間太長(執行過finish_line=267,16小時跑不完),曾經想過要將整個in.txt存進記憶體,因為到後來的資料點數為3千多,要存進3千*(3千-1)個資料,所以怕到時候記憶體會不足,有沒有什麼方式可以達到同樣的效果,並且使執行數度加快. 可能是我寫的方式不是很好,收尋到有找到有人建議使用TStringList,但是我買的書都沒有介紹到,因為沒有例子不會使用. 發表人 - k804138 於 2005/12/08 08:33:09
|
jow
尊榮會員
發表:66 回覆:751 積分:1253 註冊:2002-03-13
發送簡訊給我
|
只是建議方法,有需要請自行改寫
unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls; type
TObj = class(TPersistent)
public
s0: Char;
s1: Char;
s2: Single;
end; TForm1 = class(TForm)
Button1: TButton;
Label1: TLabel;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
end; var
Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject);
var
T: Cardinal;
I, Index: Integer;
AKey: string;
Obj: TObj;
F, G, ObjList: TStringList;
begin
T := GetTickCount;
if FileExists('C:\IN.TXT') then
begin
ObjList := TStringList.Create;
try
ObjList.Duplicates := dupIgnore;
ObjList.Sorted := True;
F := TStringList.Create;
try
F.LoadFromFile('C:\IN.TXT');
Label1.Caption := 'Source DataCount=' IntToStr(F.Count); //產生Keyd Objects
for I := 0 to F.Count-1 do
begin
AKey := F[I][1] F[I][3];
if not ObjList.Find(AKey, Index) then
begin
Obj := TObj.Create;
Obj.s0 := F[I][1];
Obj.s1 := F[I][3];
//這個初值定義不嚴謹,隨此Key出現的位置會有不同//
Obj.s2 := StrToFloat(Copy(F[I],5,Length(F[I])-4));
ObjList.AddObject(AKey, Obj);
end;
end; //Process Input Data
for I := 0 to F.Count-1 do
begin
AKey := F[I][3] F[I][1];//尋找此Key值之物件
if ObjList.Find(AKey, Index) then
begin
Obj := TObj(ObjList.Objects[Index]);
Obj.s2 := Obj.s2 StrToFloat(Copy(F[I],5,Length(F[I])-4));
end;
//沒有找到具有此Key值之物件,則此筆資料不列入計算.
end;
finally
FreeAndNil(F);
end; //Save Data to File
F := TStringList.Create;
try
for I := 0 to ObjList.Count-1 do
with TObj(ObjList.Objects[I]) do
F.Add(Format('%s %s .6f', [s0, s1, s2]));
F.SaveToFile('C:\OUT.TXT');
finally
FreeAndNil(F);
end; finally //Free All Keyed Objects
while ObjList.Count > 0 do
begin
ObjList.Objects[0].Free;
ObjList.Delete(0);
end;
FreeAndNil(ObjList); end;
end;
Label2.Caption := 'Elapsed TickCount=' IntToStr(GetTickCount-T); end; 執行結果資料筆數 131712筆(就你的資料重複複製),執行時間 500ms 其下為輸出資料: 0 1 8586.752930
0 2 7134.373535
0 3 7433.805176
1 0 8715.125977
1 2 8388.548828
1 3 7284.408203
2 0 7305.764648
2 1 8297.096680
2 3 9729.314453
3 0 7665.728516
3 1 7290.617676
3 2 10141.905273 NOTE: 請自行斟酌由字串取值的做法,這裡只就你的資料作簡單實作.
發表人 - jow 於 2005/12/08 16:15:07
|
k804138
一般會員
發表:3 回覆:4 積分:1 註冊:2005-04-04
發送簡訊給我
|
可能我還是程式初學者,你用的語法我不知道是哪種,抱歉. 我當finish_line很小的時候執行也很快,但是當finish_line(=64的時候我執行30分鐘)很大的時候要一直重複開同檔關檔,不知道是不是這邊花不少的時間. 還是我要用二維陣列去存我只是怕最後我要開的陣列[3000][3000],怕會太大.
|
RedSnow
版主
發表:79 回覆:1322 積分:845 註冊:2003-12-15
發送簡訊給我
|
k804138 您好: 請您澄清以下兩點,以便確認您的問題:
1. in.txt 檔案內的資料,是不是每一行為一個資料點的數據?換言之;是否最多為三千筆資料行? 2. 您說的三千乘以三千減一這個數字是做什麼用的?若資料筆數為 N,那麼為何要有 (N-1) * N 這樣的數字?
7 天天敲鍵盤 v 時時按滑鼠 8
|
jow
尊榮會員
發表:66 回覆:751 積分:1253 註冊:2002-03-13
發送簡訊給我
|
unit1.h //---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include
#include
#include
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TRelNode : TPersistent
{
private:
AnsiString __fastcall GetKey();
AnsiString __fastcall GetKey2();
AnsiString __fastcall GetValStr();
public:
int s0, s1;
float s2;
__property AnsiString Key = {read=GetKey};
__property AnsiString Key2 = {read=GetKey2};
__property AnsiString ValStr = {read=GetValStr};
}; class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TLabel *Label1;
TLabel *Label2;
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
void __fastcall String2Value(AnsiString Value, int *s0, int *s1, float *s2);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif unit1,cpp
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetKey()
{
AnsiString ret;
return ret.sprintf("%d %d", s0, s1);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetKey2()
{
AnsiString ret;
return ret.sprintf("%d %d", s1, s0);
}
//---------------------------------------------------------------------------
AnsiString __fastcall TRelNode::GetValStr()
{
AnsiString ret;
return ret.sprintf("%d %d %f", s0, s1, s2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::String2Value(AnsiString Value, int *s0, int *s1, float *s2)
{
int len = Value.Length();
*s0 = atoi(Value.SubString(1,1).Trim().c_str());
*s1 = atoi(Value.SubString(3,1).Trim().c_str());
*s2 = atof(Value.SubString(5,len-4).Trim().c_str());
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
}
//--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender)
{
TStringList *ObjList, *F;
TRelNode *Obj;
DWORD T = GetTickCount();
if(FileExists("C:\\IN.TXT"))
{
ObjList = new TStringList();
try
{
ObjList->Duplicates = dupIgnore;
ObjList->Sorted = true;
F = new TStringList();
try
{
F->LoadFromFile("C:\\IN.TXT");
Label2->Caption = "Input Data Count= " IntToStr(F->Count);
for(int i=0; iCount; i )
{
AnsiString AKey;
int Index, s0, s1;
float s2;
String2Value(F->Strings[i], &s0, &s1, &s2);
AKey.sprintf("%d%d", s0, s1);
if(!ObjList->Find(AKey, Index))
{
Obj = new TRelNode();
Obj->s0 = s0;
Obj->s1 = s1;
Obj->s2 = s2;
ObjList->AddObject(AKey, (TObject*)Obj);
}
} for(int i=0; iCount; i )
{
AnsiString AKey;
int Index, s0, s1;
float s2;
String2Value(F->Strings[i], &s0, &s1, &s2);
AKey.sprintf("%d%d", s1, s0);
if(ObjList->Find(AKey, Index))
{
Obj = (TRelNode*)ObjList->Objects[Index];
Obj->s2 = Obj->s2 s2;
}
}
}
__finally
{
delete F;
} F = new TStringList();
try
{
for(int i=0; iCount; i )
{
Obj = (TRelNode*)ObjList->Objects[i];
F->Add(Obj->ValStr);
}
F->SaveToFile("C:\\OUT.TXT");
}
__finally
{
delete F;
} }
__finally
{
while(ObjList->Count>0)
{
delete ObjList->Objects[0];
ObjList->Delete(0);
}
delete ObjList;
}
}
Label1->Caption = "Elapsed TickCount = " IntToStr(GetTickCount() - T); }
//---------------------------------------------------------------------------
|