還是請教前輩出現次數統計問題?? |
答題得分者是:jow
|
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
var
i,j:Integer; S3:string; done : Boolean; v_no:array of integer; i36: array[1..36] of integer; //==================================== for i := 1 TO 36 DO i36[1] := v_no[1]; for i := low(v_no) 1 TO high(v_no) DO begin i36[i] := v_no[i]; done := False; j := 1; repeat if i36[j] = i36[i] then begin // i36[i] := i36[i] - 1; j := 1; end else begin inc(j); if j >= i then done := True; end; until done; end; S3:= ''; for i := low(i36) to high(i36) do S3:= S3 FormatFloat('00',i36[i]) ' '; // 強制 0秀出 Lab_V0.CAPTION := S3;// end; ===>>問題是這樣的,v_no 內含有36組號碼,例如:25 36 45 48 59 58 27 36 25..... 要統計出 25x2 36x2 .... 小弟想不出有何方式可以完成這樣的功能,前次感謝 dllee 大師解說如何化解數字間的含字串(,),現在已經瞭解如何轉出了,但碰到這關真的沒輒。所以才引用<<排序方式>>但還是慘呀!因此只好再厚顏請教各位大師教導。先謝謝各位前輩了! |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
使用 TStringList 來處理。
TStringList 設定 Sort, 利用 Objects 來存出現次數。 同之前範例:(以下是線上亂寫的 Delphi Code 請自行除錯, 如果覺得我寫成 BCB 時,請多包涵 ) [code delphi] aSL1 := TStringList.Create; aSL2 := TStringList.Create; aSL2.Sort:=True; aSL1.CommaText:=VV; // VV 是 , 號分隔的數字字串,如 '10,20,30' for I := 0 to aSL1.Count -1 do begin index := aSL2.IndexOf(aSL1.Strings[i]); // index 是 Integer 變數 if index >=0 then // 找到在 aSL2 內, 原計數值 1 begin OldCount := Integer(aSL2.Objects[i]); // OldCount 是 Integer 變數 aSL2.Objects[i]:=TObject(OldCount 1); end; else // 不在 aSL2 內,加入並計數 1 begin aSL2.AddObject(aSL1.Strings[i],TObject(1)); end; end; message:=EmptyStr; for I := 0 to aSL2.Count -1 do begin message:=message aSL2.Strings[i] ' x ' Integer(aSL2.Objects[i]) '\n\r'; end; ShowMessage(message); [/code] ■ ShareMe 免費網路硬碟, 申請送2G, 用 MSN 幫她打廣告加 10G, 推薦1人加 1G, 活動只到 9 月底, 請把握時機 ■
------
http://www.ViewMove.com |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
============引用====================
使用 TStringList 來處理。 TStringList 設定 Sort, 利用 Objects 來存出現次數。 同之前範例:(以下是線上亂寫的 Delphi Code 請自行除錯, 如果覺得我寫成 BCB 時,請多包涵 ) [code delphi] unit fTestMain; interface uses Windows, Forms, Controls, StdCtrls, Classes; type { TObj } TObj = class(TObject) protected FNum: Integer; FCount: Integer; public constructor Create(Num: Integer); function Key: string; property Num: Integer read FNum; property Count: Integer read FCount write FCount; end; { TObj } TfrmTestMain = class(TForm) Button1: TButton; ListBox1: TListBox; Label1: TLabel; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private function RandomSample: string; end; var frmTestMain: TfrmTestMain; implementation uses SysUtils; {$R *.dfm} function _split_(S,Delimiter: string): TStringList; begin Result := TStringList.Create; Result.Text := StringReplace(S,Delimiter,#13,[rfReplaceAll,rfIgnoreCase]); end; { TObj } constructor TObj.Create(Num: Integer); begin inherited Create; FNum := Num; end; function TObj.Key: string; begin Result := Format('%5.5d', [FNum]);//記得取足夠位數 end; { TfrmTestMain } procedure TfrmTestMain.FormCreate(Sender: TObject); begin Randomize; end; function TfrmTestMain.RandomSample: string; var I, R: Integer; begin Randomize; Result := ''; for I := 0 to 999 do begin R := Random(MaxInt) mod 100 1; Result := Result IntToStr(R) ','; end; end; procedure TfrmTestMain.Button1Click(Sender: TObject); var I, Index, Num: Integer; Key: string; O: TObj; L: TStringList; CountList : TStringList; begin CountList := TStringList.Create; try CountList.Sorted := True; //Counting L := _split_(RandomSample, ','); try for I := 0 to L.Count-1 do begin Num := StrToInt(Trim(L[I])); Key := Format('%5.5d', [Num]); if not CountList.Find(Key, Index) then Index := CountList.AddObject(Key, TObj.Create(Num)); O := TObj(CountList.Objects[Index]); if O <> nil then Inc(O.FCount); end; finally FreeAndNil(L); end; //Show Result L := TStringList.Create; try for I := 0 to CountList.Count-1 do with TObj(CountList.Objects[I]) do L.Add(Key ', ' IntToStr(Count)); ListBox1.Items.Text := L.Text; finally FreeAndNil(L); end; finally //Free Data Objects for I := 0 to CountList.Count-1 do CountList.Objects[I].Free; FreeAndNil(CountList); end; end; end. [/code]
編輯記錄
jow 重新編輯於 2007-09-28 09:21:09, 註解 無‧
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
哈哈, 還是要會 Delphi 寫出來才像樣
在 BCB 內,我常把 TObject* 或 void* 存一些有的沒有的,用強制轉型去亂搞 在 Delphi 比較少看到這樣使用,當然,還是像 jow 好好寫一個 TObject 的元件來處理 是比較好的作法,不然,就有有更多的問題,如: 為何Object 與 integer可以互轉 ■ Seednet ShareMe 免費網路硬碟, 申請送2G, 用 MSN 幫她打廣告加 10G, 推薦1人加 1G, 活動只到 9 月底, 請把握時機 ■
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 dllee 文 章=================== 使用 TStringList 來處理。 TStringList 設定 Sort, 利用 Objects 來存出現次數。 同之前範例:(以下是線上亂寫的 Delphi Code 請自行除錯, 如果覺得我寫成 BCB 時,請多包涵 ) [code delphi] aSL1 := TStringList.Create; aSL2 := TStringList.Create; aSL2.Sort:=True; aSL1.CommaText:=VV; // VV 是 , 號分隔的數字字串,如 '10,20,30' for I := 0 to aSL1.Count -1 do begin index := aSL2.IndexOf(aSL1.Strings[i]); // index 是 Integer 變數 if index >=0 then // 找到在 aSL2 內, 原計數值 1 begin OldCount := Integer(aSL2.Objects[i]); // OldCount 是 Integer 變數 aSL2.Objects[i]:=TObject(OldCount 1); end; else // 不在 aSL2 內,加入並計數 1 begin aSL2.AddObject(aSL1.Strings[i],TObject(1)); end; end; message:=EmptyStr; for I := 0 to aSL2.Count -1 do begin message:=message aSL2.Strings[i] ' x ' Integer(aSL2.Objects[i]) '\n\r'; end; ShowMessage(message); [/code] ==========>>謝謝 dllee 大師指導,小弟把上述程式碼引用編譯之後出現, message:=message aSL2.Strings[i] ' x ' Integer(aSL2.Objects[i]) '\n\r'; ---> Incompatible Type 請問 是message 定義宣告為 string 錯了嗎? ■ ShareMe 免費網路硬碟, 申請送2G, 用 MSN 幫她打廣告加 10G, 推薦1人加 1G, 活動只到 9 月底, 請把握時機 ■ |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
再試試:
message:=message aSL2.Strings[i] ' x ' String(Integer(aSL2.Objects[i])) '\n\r'; message 是 string 的變數。 如果還是不行,請試試 jow 的版本,可以學到更多喔。因為我只是亂寫 Delphi code ■ Seednet ShareMe 免費網路硬碟, 申請送2G, 用 MSN 幫她打廣告加 10G, 推薦1人加 1G, 活動只到 9 月底, 請把握時機 ■
------
http://www.ViewMove.com |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
再給你dllee 大大的版本
[code delphi] procedure TfrmTestMain.Button2Click(Sender: TObject); var I, Index, Count: Integer; L, CountList: TStringList; begin CountList := TStringList.Create; try //Counting L := _split_(RandomSample, ','); try for I := 0 to L.Count-1 do begin Index := CountList.IndexOf(L[I]); if Index = -1 then Index := CountList.AddObject(L[I], TObject(0)); Count := Integer(CountList.Objects[Index]); CountList.Objects[Index] := TObject(Count 1); end; finally FreeAndNil(L); end; //Show Result CountList.Sorted := True; L := TStringList.Create; try for I := 0 to CountList.Count-1 do begin Count := Integer(CountList.Objects[I]); L.Add(CountList[I] ', ' IntToStr(Count)); end; ListBox1.Items.Text := L.Text; finally FreeAndNil(L); end; finally FreeAndNil(CountList); end; end; [/code] |
syntax
尊榮會員 發表:26 回覆:1139 積分:1258 註冊:2002-04-23 發送簡訊給我 |
如果資料量與範圍,在可接受狀況下
就不要在排來排去的了 var len: Integer; CountI: array of Integer; len := 0; for i := Low(v_no) to Height(v_no) do len := len or v_no[i]; ---> 計算 SetLength(CountI, len); <----- 若範圍已知,那直接填,還可以省一回圈時間 for i := Low(v_no) to Height(v_no) do Inc(CountI[v_no[i]); ---> 計算 for i := Low(CountI) to Height(CountI) do if CountI > 0 then xxxxxxxxx do what you want; ---> 顯示 最多 3n 最少 2n 比 2n??? ln 快 ===================引 用 K1086 文 章=================== var i,j:Integer; S3:string; done : Boolean; v_no:array of integer; i36: array[1..36] of integer; //==================================== for i := 1 TO 36 DO i36[1] := v_no[1]; for i := low(v_no) 1 TO high(v_no) DO begin i36[i] := v_no[i]; done := False; j := 1; repeat if i36[j] = i36[i] then begin // i36[i] := i36[i] - 1; j := 1; end else begin inc(j); if j >= i then done := True; end; until done; end; S3:= ''; for i := low(i36) to high(i36) do S3:= S3 FormatFloat('00',i36[i]) ' '; // 強制 0秀出 Lab_V0.CAPTION := S3;// end; ===>>問題是這樣的,v_no 內含有36組號碼,例如:25 36 45 48 59 58 27 36 25..... 要統計出 25x2 36x2 .... 小弟想不出有何方式可以完成這樣的功能,前次感謝 dllee 大師解說如何化解數字間的含字串(,),現在已經瞭解如何轉出了,但碰到這關真的沒輒。所以才引用<<排序方式>>但還是慘呀!因此只好再厚顏請教各位大師教導。先謝謝各位前輩了! |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 syntax 文 章=================== 如果資料量與範圍,在可接受狀況下 就不要在排來排去的了 var len: Integer; CountI: array of Integer; len := 0; for i := Low(v_no) to Height(v_no) do len := len or v_no[i]; ---> 計算 (請問 syntax 這行為何在 編譯時會出現 分號問題??) SetLength(CountI, len); <----- 若範圍已知,那直接填,還可以省一回圈時間 for i := Low(v_no) to Height(v_no) do Inc(CountI[v_no[i]); ---> 計算 (請問 syntax 這行為何在 編譯時會出現 分號問題??) for i := Low(CountI) to Height(CountI) do if CountI > 0 then xxxxxxxxx do what you want; ---> 顯示 (這行小弟無法瞭解是何意義??可否解說清楚點。) 最多 3n 最少 2n 比 2n??? ln 快 ===================引 用 K1086 文 章=================== var i,j:Integer; S3:string; done : Boolean; v_no:array of integer; i36: array[1..36] of integer; //==================================== for i := 1 TO 36 DO i36[1] := v_no[1]; for i := low(v_no) 1 TO high(v_no) DO begin i36[i] := v_no[i]; done := False; j := 1; repeat if i36[j] = i36[i] then begin // i36[i] := i36[i] - 1; j := 1; end else begin inc(j); if j >= i then done := True; end; until done; end; S3:= ''; for i := low(i36) to high(i36) do S3:= S3 FormatFloat('00',i36[i]) ' '; // 強制 0秀出 Lab_V0.CAPTION := S3;// end; ===>>問題是這樣的,v_no 內含有36組號碼,例如:25 36 45 48 59 58 27 36 25..... 要統計出 25x2 36x2 .... 小弟想不出有何方式可以完成這樣的功能,前次感謝 dllee 大師解說如何化解數字間的含字串(,),現在已經瞭解如何轉出了,但碰到這關真的沒輒。所以才引用<<排序方式>>但還是慘呀!因此只好再厚顏請教各位大師教導。先謝謝各位前輩了! |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 jow 文 章=================== 再給你dllee 大大的版本 [code delphi] procedure TfrmTestMain.Button2Click(Sender: TObject); var I, Index, Count: Integer; L, CountList: TStringList; begin CountList := TStringList.Create; try //Counting L := _split_(RandomSample, ','); (小弟也引用 jow 您的方式 為何這行編譯不通過??) try for I := 0 to L.Count-1 do begin Index := CountList.IndexOf(L[I]); if Index = -1 then Index := CountList.AddObject(L[I], TObject(0)); Count := Integer(CountList.Objects[Index]); CountList.Objects[Index] := TObject(Count 1); end; finally FreeAndNil(L); end; //Show Result CountList.Sorted := True; L := TStringList.Create; try for I := 0 to CountList.Count-1 do begin Count := Integer(CountList.Objects[I]); L.Add(CountList[I] ', ' IntToStr(Count)); end; ListBox1.Items.Text := L.Text; finally FreeAndNil(L); end; finally FreeAndNil(CountList); end; end; [/code] |
懷舊的人
高階會員 發表:28 回覆:152 積分:141 註冊:2003-01-08 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 jow 文 章=================== 是不是漏了這個Function. implementation uses SysUtils; {$R *.dfm} function _split_(S,Delimiter: string): TStringList; begin Result := TStringList.Create; Result.Text := StringReplace(S,Delimiter,#13,[rfReplaceAll,rfIgnoreCase]); end; =====>>>是漏了 這段,但小弟有加上之後,編譯成功但卻沒有答案,請問 (jow) 前輩可否再提供比較單純化一點的解決程式讓小弟能完成這個功能,對自己學習 delphi 更有信心好嗎??, =====>>>其實我這問題是前次曾經提出的,已經有轉入毫無含(,)的字串36組號碼,如上述舉例的,現在小弟要解決的問題是在這36組號碼中,分解出相同顯示的號碼次數統計列出,例如:25x3 36x2 58x2 .....因此說前段整合36組號碼已經轉入由 vv:string; 這個變數中,現在只要再 分解 vv 這變數內的36組號碼就ok了,沒想到光這問題小弟就是折騰好久沒有答案,實想不甘心好不容易練到有些成就卻在此受困,真的有那麼難嗎?? |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
K1086 寫程式真的不難,難的是程式的設計/規劃,及用對的方法。
不論用什麼電腦語言實作,都要先有規劃,如處理流程,虛擬碼等,之後再看使用什麼語言實作。 原問題 有四組人員分銷商品,A組賣出商品價位是:25 38 65 18 27 89 45 75 23 B組賣出商品價位是:26 38 89 18 42 92 47 75 23 C組賣出商品價位是:45 75 65 27 32 89 18 42 48 D組賣出商品價位是:20 27 45 37 32 92 18 38 26 現在要求合併總列出四組賣出商品價位及數量:例如:25X1 38X3 65X2 ....以此類推 處理流程: 1. 資料輸入 2. 資料處理(找出相同的價位及相同的數量) 3. 資料輸出 以上的處理流程,我想,不論會不會寫程式,都應該要有這個基本的資料處理概念。 ■ 資料輸入:可以寫死在程式內,可以由 UI 輸入,可以由檔案讀入,可以用很多不同的方式。 如果老師沒有指定,或是客戶沒有要求,寫死在程式中是最簡單的方法,第二簡單是由 UI 輸入,大部分入門的書在前幾章都應該只用 Console 模組,輸出到 Console 或由 Console 讀入使用者輸入的文字,將輸入的文字轉成數字存到陣列中,即可完成資料輸入。若 TStringList 用熟,由檔案讀入也是很方便的,例如,把資料以 25 38 65 ... 存成一個文字檔,用 TStringList 的 LoadFromFile 讀入,也是很方便的。 方法真的很多,以上只是取簡單的幾種作說明。 ■ 資料處理:資料已放在指定的陣列或變數或是準備要處理的空間,再來就是看如何去處理它。 題目是找出相同的價位及相同的數量,方法也真的很多,以下只是簡單處理的虛擬碼 宣告: 整數陣列 原始資料[N]; 整數陣列 價位[N]; 整數陣列 數量[N]; 整數 n, i; 實作: 將 價位[ ] 及 數量[ ] 陣列內容歸零 將資料輸入到 原始資料[ ] 陣列內 迴圈 n = 0 到 N-1 如果 原始資料[ n ] 在 價位[ ] 陣列內 則 找到那個元素的索引值,並將數量[ ] 陣列對應的元素數值 1 否則 在價位[ ] 陣列加入此新的數值,並設定數量[ ] 陣列對應的元素數值為 1 結束迴圈 將資料輸出 ■ 資料輸出:方法也很多,用訊息視窗或寫入檔案,或是輸出到 Console 等等。 要有以上初步的規劃,同時也認為這個規劃在邏輯上可行,才開始動手以程式語言實作。 當然在實作的過程,可能會因為語言的差異性或熟悉度等問題,得修改原有的規劃,但修改 後的規劃仍在邏輯上是可行的才可以。 資料輸入/資料輸出的方式,方法雖然很多種,但寫久了常用的也就是那幾種,重點是資料的處理。 以原本問題我第一次的回覆在資料處理的部分虛擬碼如下: ■ 資料處理: 宣告: 整數陣列 原始資料[N]; 整數陣列 價位[N]; 整數陣列 數量[N]; 整數 不同價位個數; 整數 n, i; 實作: 將 價位[ ] 及 數量[ ] 陣列內容歸零 將 不同價位個數 歸零 將資料輸入到 原始資料[ ] 陣列內 BubbeSort(原始資料) ; // 叫用之前已寫好的 BubbleSort 將 原始資料[ ] 排序好 價位[ 0 ] = 原始資料[ 0 ]; // 初始 數量[ 0 ] = 1; 不同價位個數 = 1; 迴圈 n = 1 到 N-1 如果 原始資料[ n ] = 價位[ 不同價位個數-1 ] 則 數量[ 不同價位個數-1 ] = 數量[ 不同價位個數-1 ] 1 否則 價位[ 不同價位個數 ] = 原始資料[ n ] 數量[ 不同價位個數 ] = 1 不同價位個數 = 不同價位個數 1 結束迴圈 將 資料輸出(將 價位[ ] 及 數量[ ] 陣列輸出,個數有 不同價位個數 個) 如果您的 請教各位為何泡沫排序方式正確,但卻結果錯誤? 已可以作好 Bobble Sort,按 我第一次的回覆 就應該可以完成了。參考以上虛擬碼再試試看。 或許你會認為,那麼小的程式還要那麼麻煩寫規劃及虛擬碼,太浪費時間了! 但這本來就是初學者應該要作的練習,沒有人是一生下來就會的 Delphi/C/C 的,沒作好 基礎的學習,使用 Delphi/BCB/VB 只是讓你很快可以作出「空」架子程式,卻沒有內容。 以您的問題,解法至少數10種,每個人每天說一種,你試也試不完,當然,如果你花時間 一個一個都去試出來,一次就可以學到很多種不同的解法。 最後給您一個建議,如果您還是學生,在前一篇我已把初學者真要的學好語言的步驟方法 都說得很清楚了,請一步一步慢慢來,如果對電腦語言沒興趣,又這些只是因為作業需要, 那... 找同學的來改一改比較快(以曾任講師的我, 說這樣的話也許不適當, 但如果對電腦語言 沒興趣, 那也無法強求),因為以現在的環境,學會電腦語言也不是什麼大不了專長,再加上 還是 Delphi 算是業界冷門的語言,如果沒興趣,還不如去學其他的專長,對未來更有效益。 如果很不幸你已是上班族(應該不可能是吧),那我看... 還是改行會比較好... ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 dllee 文 章=================== K1086 寫程式真的不難,難的是程式的設計/規劃,及用對的方法。 不論用什麼電腦語言實作,都要先有規劃,如處理流程,虛擬碼等,之後再看使用什麼語言實作。 原問題 有四組人員分銷商品,A組賣出商品價位是:25 38 65 18 27 89 45 75 23 B組賣出商品價位是:26 38 89 18 42 92 47 75 23 C組賣出商品價位是:45 75 65 27 32 89 18 42 48 D組賣出商品價位是:20 27 45 37 32 92 18 38 26 現在要求合併總列出四組賣出商品價位及數量:例如:25X1 38X3 65X2 ....以此類推 處理流程: 1. 資料輸入 2. 資料處理(找出相同的價位及相同的數量) 3. 資料輸出 以上的處理流程,我想,不論會不會寫程式,都應該要有這個基本的資料處理概念。 ■ 資料輸入:可以寫死在程式內,可以由 UI 輸入,可以由檔案讀入,可以用很多不同的方式。 如果老師沒有指定,或是客戶沒有要求,寫死在程式中是最簡單的方法,第二簡單是由 UI 輸入,大部分入門的書在前幾章都應該只用 Console 模組,輸出到 Console 或由 Console 讀入使用者輸入的文字,將輸入的文字轉成數字存到陣列中,即可完成資料輸入。若 TStringList 用熟,由檔案讀入也是很方便的,例如,把資料以 25 38 65 ... 存成一個文字檔,用 TStringList 的 LoadFromFile 讀入,也是很方便的。 方法真的很多,以上只是取簡單的幾種作說明。 ■ 資料處理:資料已放在指定的陣列或變數或是準備要處理的空間,再來就是看如何去處理它。 題目是找出相同的價位及相同的數量,方法也真的很多,以下只是簡單處理的虛擬碼 宣告: 整數陣列 原始資料[N]; 整數陣列 價位[N]; 整數陣列 數量[N]; 整數 n, i; 實作: 將 價位[ ] 及 數量[ ] 陣列內容歸零 將資料輸入到 原始資料[ ] 陣列內 迴圈 n = 0 到 N-1 如果 原始資料[ n ] 在 價位[ ] 陣列內 則 找到那個元素的索引值,並將數量[ ] 陣列對應的元素數值 1 否則 在價位[ ] 陣列加入此新的數值,並設定數量[ ] 陣列對應的元素數值為 1 結束迴圈 將資料輸出 ■ 資料輸出:方法也很多,用訊息視窗或寫入檔案,或是輸出到 Console 等等。 要有以上初步的規劃,同時也認為這個規劃在邏輯上可行,才開始動手以程式語言實作。 當然在實作的過程,可能會因為語言的差異性或熟悉度等問題,得修改原有的規劃,但修改 後的規劃仍在邏輯上是可行的才可以。 資料輸入/資料輸出的方式,方法雖然很多種,但寫久了常用的也就是那幾種,重點是資料的處理。 以原本問題我第一次的回覆在資料處理的部分虛擬碼如下: ■ 資料處理: 宣告: 整數陣列 原始資料[N]; 整數陣列 價位[N]; 整數陣列 數量[N]; 整數 不同價位個數; 整數 n, i; 實作: 將 價位[ ] 及 數量[ ] 陣列內容歸零 將 不同價位個數 歸零 將資料輸入到 原始資料[ ] 陣列內 BubbeSort(原始資料) ; // 叫用之前已寫好的 BubbleSort 將 原始資料[ ] 排序好 價位[ 0 ] = 原始資料[ 0 ]; // 初始 數量[ 0 ] = 1; 不同價位個數 = 1; 迴圈 n = 1 到 N-1 如果 原始資料[ n ] = 價位[ 不同價位個數-1 ] 則 數量[ 不同價位個數-1 ] = 數量[ 不同價位個數-1 ] 1 否則 價位[ 不同價位個數 ] = 原始資料[ n ] 數量[ 不同價位個數 ] = 1 不同價位個數 = 不同價位個數 1 結束迴圈 將 資料輸出(將 價位[ ] 及 數量[ ] 陣列輸出,個數有 不同價位個數 個) 如果您的 請教各位為何泡沫排序方式正確,但卻結果錯誤? 已可以作好 Bobble Sort,按 我第一次的回覆 就應該可以完成了。參考以上虛擬碼再試試看。 或許你會認為,那麼小的程式還要那麼麻煩寫規劃及虛擬碼,太浪費時間了! 但這本來就是初學者應該要作的練習,沒有人是一生下來就會的 Delphi/C/C 的,沒作好 基礎的學習,使用 Delphi/BCB/VB 只是讓你很快可以作出「空」架子程式,卻沒有內容。 以您的問題,解法至少數10種,每個人每天說一種,你試也試不完,當然,如果你花時間 一個一個都去試出來,一次就可以學到很多種不同的解法。 最後給您一個建議,如果您還是學生,在前一篇我已把初學者真要的學好語言的步驟方法 都說得很清楚了,請一步一步慢慢來,如果對電腦語言沒興趣,又這些只是因為作業需要, 那... 找同學的來改一改比較快(以曾任講師的我, 說這樣的話也許不適當, 但如果對電腦語言 沒興趣, 那也無法強求),因為以現在的環境,學會電腦語言也不是什麼大不了專長,再加上 還是 Delphi 算是業界冷門的語言,如果沒興趣,還不如去學其他的專長,對未來更有效益。 如果很不幸你已是上班族(應該不可能是吧),那我看... 還是改行會比較好... ====>> 謝謝 dllee 大師指導,小弟已經有做到這個,可以秀出 25x1 的效果 可是中間的 變數連繫判斷相同與不相同的要列出就不知如何下手了,請大師再給小弟說說或是做給小弟研究看看好嗎?? var Hsno:string; n,i:Integer; VV:= StringReplace(VV,' ','',[rfReplaceAll]);//把總加字串刪掉中間空白 N:= length(VV) div 2; setlength(Hsno,N); for i:=1 to N do begin HSno[i-1]:= copy(VV,i*2-1,2); end; Lab_V0.Caption:= ' '; K:=0; for i:=1 to N do begin K:= StrToIntDef(HSno[i-1],1); if K = 25 Then Lab_V0.Caption:= FormatFloat('00',K) 'x 1' else if k = 58 Then Lab_V0.Caption:= FormatFloat('00',K) 'x 1'; end; end; |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
研究所指導老師常向我抱怨現在的新世代學生都太有創意了,
學生在本週實作時,遇到了一些問題,向老師回報了, 老師就提出方法、流程、步驟給學生參考,請學生下週再回報處理狀況, 很妙的是,學生通常不會按老師的建議去作,會有自己的想法,並去實作 自己的想法,下週學生再來 Meeting 的時候,會提出當週遇到的新狀況, 而這些新況與舊狀況完全不同,而且老師前一週給學生的方法步驟, 學生也都沒有回報那些方法、流程或步驟是否有問題, 等於是每次都給老師新的題目,而且是老師無法由學生的回報得知之前的 判斷是否正常,也就很難對學生作進一步的指導。 目前您的問題就像這樣。 看您的程式與我說的方法、流程、步驟完全不同,我無法提供進一步的協助, 請您按我的虛擬碼寫,不然,請您按您自己的方法作。 程式不是東貼西湊就可以作到想要的結果的。 ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
另一種土製想法(沒空實作,提供想法)
1.你已經把 V_NO 轉入 I36的陣列中,也就是 I36[1]=25 (假設) 2.可以宣告一組 c36: array[0..36] of integer; for i:= 1 to length(i36) do begin c36[i36[i]]:= c36[i36[i]] 1; end; 這段的做法就是,例如 i36[1]=25 那我就令 c36[25] 內存值 1, i36[6]=25 那程式會使 c36[25] 再加1 (當 i 執行到 6 時 等全部都跑完,你只要去算 c36[i]內的各值是多少,就可以求出 V_NO 中的統計 但這種做法不適用於要開出大的陣列值,例如你的 V_NO 有 65536值,那就必須開始 C36[0..65536]出來,這是很可怕的 ===================引 用 K1086 文 章=================== var i,j:Integer; S3:string; done : Boolean; v_no:array of integer; i36: array[1..36] of integer; //==================================== for i := 1 TO 36 DO i36[1] := v_no[1]; for i := low(v_no) 1 TO high(v_no) DO begin i36[i] := v_no[i]; done := False; j := 1; repeat if i36[j] = i36[i] then begin // i36[i] := i36[i] - 1; j := 1; end else begin inc(j); if j >= i then done := True; end; until done; end; S3:= ''; for i := low(i36) to high(i36) do S3:= S3 FormatFloat('00',i36[i]) ' '; // 強制 0秀出 Lab_V0.CAPTION := S3;// end; ===>>問題是這樣的,v_no 內含有36組號碼,例如:25 36 45 48 59 58 27 36 25..... 要統計出 25x2 36x2 .... 小弟想不出有何方式可以完成這樣的功能,前次感謝 dllee 大師解說如何化解數字間的含字串(,),現在已經瞭解如何轉出了,但碰到這關真的沒輒。所以才引用<<排序方式>>但還是慘呀!因此只好再厚顏請教各位大師教導。先謝謝各位前輩了! |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
感謝 P.D版主指導 小弟努力學習,最後終於決定用資料庫自動運算方式解決,出現次數但還是有計算次數錯誤,現在把片段程式呈上請大師指導錯誤在那裡,謝謝!
VJ:=COPY(DATETOSTR(Date_1.Date),1,4); //先刪除再新增 T496_234Fm1.Query1.CLOSE; T496_234Fm1.Query1.SQL.Clear; T496_234Fm1.Query1.SQL.ADD('DELETE FROM Pno_36 WHERE NOitem>=''' VJ ''' '); T496_234Fm1.Query1.ExecSQL; FOR I:=1 TO 36 DO //先把1~36的數都寫到資料庫,再由資料庫排序 BEGIN T496_234Fm1.Query1.CLOSE; T496_234Fm1.Query1.SQL.Clear; T496_234Fm1.Query1.Params.Clear; T496_234Fm1.Query1.SQL.ADD('INSERT INTO Pno_36(NOitem,NO36,NOtime)'); T496_234Fm1.Query1.SQL.ADD('VALUES(:NOitem, :NO36, :NOtime)'); T496_234Fm1.Query1.PARAMByName('NOitem').ASSTRING:=VJ; T496_234Fm1.Query1.PARAMByName('NO36').ASSTRING:=COPY(VV,i*2-1,2); if LENGTH(VV[I]) = 1 THEN T496_234Fm1.Query1.PARAMByName('NOtime').ASSTRING:=VV[I] else T496_234Fm1.Query1.PARAMByName('NOtime').ASSTRING:=VV[I]; T496_234Fm1.Query1.ExecSQL; end; 出現的結果是這樣.... 正確36組是.. 06 17 28 39 41 12 23 34 45 29 30 31 39 48 19 49 09 40 21 22 23 31 41 11 42 01 32 25 24 26 35 45 14 46 04 36 請問是 NOtime 比較方式錯了嗎??? |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
沒想到我潛水一個月,K1086也潛水一個月呀
潛水一個月後,您還是提出了「新的方案」,這樣子是會作不完的喔。 還好您是不接案或上班,不然,可能就沒業績了。 就算是當學生,可以東學學、西看看,每天學新的東西、試新的方案, 但是,還是建議您,把舊的方案的問題找出來,再繼續,才會得到 經驗,不然,每次都是重新開始,經驗無法累積。而寫程式很多時候 就只是看誰的經驗多而已。 ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
var
m2:integer; s36:string; k36: array of STRING; P36: ARRAY[1..36] OF STRING; Lab_E2.Caption :=' '; for I:=1 TO 36 DO M2:=0; M2:= length(VV) div 2; setlength(k36,M2); for i:=1 to M2 do begin K36[i-1]:= copy(VV,i*2-1,2); Lab_E2.Caption :=Lab_E2.Caption k36[i-1]; end; begin FOR I:=1 TO 36 DO begin if LENGTH(INTTOSTR(I)) < 2 THEN S36:='0' INTTOSTR(I); if S36=k36[i] Then P36[I]:=INTTOSTR(STRTOINT(P36[I]) 1); end; Dllee 前輩你給小弟的提示,我直接運用字串比較方式,如上的方法,是簡易法但還是無法完成,請問用這種方式對嗎?? |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
我完全看不懂您的邏輯。
請您先把您要處理的流程寫下來,一步一步作。 先確流程是可得到想要的結果的,再按該流程實作程式。 不然猜您的程式變數,沒人知道您想作什麼。 ===================引 用 K1086 文 章=================== var m2:integer; s36:string; k36: array of STRING; P36: ARRAY[1..36] OF STRING; →是要用來計數嗎 ? Lab_E2.Caption :=' '; for I:=1 TO 36 DO →為什麼這要 for loop? M2:=0; →是要重置 P36 嗎? M2:= length(VV) div 2; setlength(k36,M2); for i:=1 to M2 do begin K36[i-1]:= copy(VV,i*2-1,2); →K36[ ] 存著數值字串 Lab_E2.Caption :=Lab_E2.Caption k36[i-1]; end; begin FOR I:=1 TO 36 DO begin if LENGTH(INTTOSTR(I)) < 2 THEN S36:='0' INTTOSTR(I); → S36 會是 01 02 03 ... 36 的字串? if S36=k36[i] Then → 與 K36 數值字串是否相同? P36[I]:=INTTOSTR(STRTOINT(P36[I]) 1); → 相同累加 P36[ ] ? P36[ ] 是用來計數的嗎? end; Dllee 前輩你給小弟的提示,我直接運用字串比較方式,如上的方法,是簡易法但還是無法完成,請問用這種方式對嗎??
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
===================引 用 dllee 文 章=================== 我完全看不懂您的邏輯。 請您先把您要處理的流程寫下來,一步一步作。 先確流程是可得到想要的結果的,再按該流程實作程式。 不然猜您的程式變數,沒人知道您想作什麼。 ===================引 用 K1086 文 章=================== var m2:integer; s36:string; k36: array of STRING; P36: ARRAY[1..36] OF STRING; →是要用來計數嗎 是用來放置統計後的 號碼如 25 1 Lab_E2.Caption :=' '; for I:=1 TO 36 DO →為什麼這要 for loop? 是切割字串導入 k36 運算的 M2:= length(VV) div 2; setlength(k36,M2); for i:=1 to M2 do begin K36[i-1]:= copy(VV,i*2-1,2); →K36[ ] 存著數值字串 關於 1 to 36 若改成 1 to 99 就可以完成希望比較的未來值,對嗎?? begin if LENGTH(INTTOSTR(I)) < 2 THEN S36:='0' INTTOSTR(I); → S36 會是 01 02 03 ... 36 的字串? 對是這個意思,只是覺得很奇怪明明是一樣字串為何無法相等,所以條件就無法成立。 end; Dllee 前輩你給小弟的提示,我直接運用字串比較方式,如上的方法,是簡易法但還是無法完成,請問用這種方式對嗎?? |
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
之前回應的實作程式碼, 不論是資料物件的版本, 還是
另一個實作dllee版大想法的版本, 都是測試OK的, 而且不管數值的大小,也都可以依樣來處理, 建議你細心琢磨. 以下再給你一個簡易的做法, 供你參考.... [code delphi] procedure TForm1.Button3Click(Sender: TObject); const SSS='06 17 28 39 41 12 23 34 45 29 30 31 39 48 19 49 09 40 21' ' 22 23 31 41 11 42 01 32 25 24 26 35 45 14 46 04 36'; var I, V: Integer; L: TStringList; A: array of Integer; begin SetLength(A, 99); try L := TStringList.Create; try L.Delimiter := #32; L.DelimitedText := SSS; for I := 0 to L.Count-1 do begin V := StrToIntDef(L[I],-1); if (V>-1) and (V end; finally FreeAndNil(L); end; for I := 0 to Length(A)-1 do if A[I] > 0 then ListBox1.Items.Add(Format('A[%2.2d]=%d',[I,A[I]])); ListBox1.Items.SaveToFile('D:\OUTPUT.TXT'); finally A := nil; end; end; [/code] 執行結果 : D:\OUTPUT.TXT 的內容 A[01]=1 A[04]=1 A[06]=1 A[09]=1 A[11]=1 A[12]=1 A[14]=1 A[17]=1 A[19]=1 A[21]=1 A[22]=1 A[23]=2 A[24]=1 A[25]=1 A[26]=1 A[28]=1 A[29]=1 A[30]=1 A[31]=2 A[32]=1 A[34]=1 A[35]=1 A[36]=1 A[39]=2 A[40]=1 A[41]=2 A[42]=1 A[45]=2 A[46]=1 A[48]=1 A[49]=1 |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
jow 真是太好心了
建議 K1086 如果您想自己寫,請先整理出想要處理的流程,先確認該流程可行,再寫對應的程式。 再不然,參考 jow 的版本,把每一程式區塊的用途或技巧學起來,用 Delphi 單步執行,執行過程查看變數內容,可以更了解別人程式的作用或用意,這樣才能知道要如何去用 Delphi 提供現成的功能。這是基本功,必需花時間去學習的。 日後在處理時,同樣是整理想要處理的流程,但因為您已更熟悉 Delphi,因此在想處理流程時,可能就會連如何使用 Delphi 功能或用什麼資料結構或演算法去實現,如此,基本功愈好的,在初步規劃的流程或作法的可行性就提高,也可加快整體程式或系統的開發。 而您目前所缺的就是基本功。加油囉。 ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
謝謝 Dllee and Jow 兩位大師__不厭我煩__的一再敦促,小弟實感欣慰,K-Top真的是Delphi學習者溫馨可愛的家,自從小弟由門外漢混進以來,始終一直抱持著努力認真學習的心態,對於各位大師或前輩們的種種建言,當然0的接受,小弟坦白說也會如孔子說的:不恥下問,所以有時提問或自以為是的片段程式等等..,自然就發表了,祈請見諒!
報告 Dllee 大師 小弟已經慢慢領悟到學寫 Delphi 程式的訣竅,相信有一天小弟會呈現所學習成果的模擬程式給大師檢驗,人說天下無難事只怕有心人,您們說對嗎? |
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
不要叫我大師啦, 我不夠格啦。
只是,要寫程式,真的要有興趣再來寫,不然,有太多更好的出路, 沒興趣硬要來寫程式,是浪費生命的。 看看 G01 的 [分享] 不過就是人性,一個感恩的心 !! 你引以為恥嗎? 內的分享資料, 檢視一下自己是否真的適合作程式設計,如這篇所分享的連結,所提的,寫程式 其實在台灣出路及成就都不會太好的,我是已經中毒太深了,無法自拔... ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
暗黑破壞神
版主 發表:9 回覆:2301 積分:1627 註冊:2004-10-04 發送簡訊給我 |
|
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
|
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
To 暗黑,
那有那麼好, 現在就可以等退休... 純軟愈來愈難賺了... 最近接洽有些比較接近純軟(還是要與機台連線), 價格就低到不行... 還是您有人包養比較好 To K1086, 給誰分不重要, 重要是要學到東西。 jow 大花那麼多時間幫你除錯, 寫程式,我只是打屁而已.. 哈哈~~ ■ VMASK - ViewMove Automation Software Kernel ■ VMIO-Server/SECS/GEM ■ dllee's blog ■ dllee's StatPlus ■
------
http://www.ViewMove.com |
K1086
初階會員 發表:63 回覆:148 積分:42 註冊:2007-04-09 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |