(* Define record structure name name Gaoshu advanced Math English computer computer avage average score *) type Sturecord ={name:string, Gaoshu:r
EAL, English:real, Computer:real, avage:real};
(* Open file, ready to read data *) Val my_in = Textio.openin ("Datas.txt");
(* Read the data in the file into a string list *) val str_list = [];
Fun Createstringlist (l,0) = L |createstringlist (l,n:int) = Createstringlist (Valof (Textio.inputline (my_in)):: l,n-1);
(* createstringlist (str_list,2) 12 is the number of records *) Val str_list = Createstringlist (str_list,12); (* Convert string list to record linked list *) Fun createrecordlist (line_str:string) = Make fun NOTC (C:char) = fn c ' = = C=c ' val Stuin fo = substring.tokens (NOTC # ",") (Substring.full line_str) val name_stu:string = substring.string (List.nth (stuInfo,0 )) Val gaoshu_score:real = Valof (real.fromstring (substring.string (List.nth))) Val stuinfo,1 = Valof (Real.fromstring (substring.string (List.nth (stuinfo,2)))) Val computer_score:real = Valof (Real.fromString ( Substring.string (List.nth (Stuinfo,3))) Val avage_sroce:real = (gaoshu_score+english_score+computer_score)/Real (3) Val Recorda:sturecord = {n
AME=NAME_STU,GAOSHU=GAOSHU_SCORE,ENGLISH=ENGLISH_SCORE,COMPUTER=COMPUTER_SCORE,AVAGE=AVAGE_SROCE} in Recorda end;
(* List.map apply createrecordlist function to each element of the Str_list list record_list generate the record list *)
(* The Map function iterates through the list *) val record_list:sturecord list = List.map createrecordlist str_list;
(* Close File *)
Textio.closein (my_in); (* Add record does not consider an orderly increase, just simply add to the table header *) val Newrecord:sturecord = {name= "pitter", gaoshu=99.0,english=89.0,computer=90.0,avage=
(99.0+89.0+90.0)/3.0};
Val Record_list:sturecord list = newrecord::record_list; (* Printing function first parameter: List of the second parameter: the location to print, if negative one (to) print "t exist" means record does not exist *) Fun Printrecord (l,~1) = "Don t exist" | Printrecord (L,n:int) = Let (*list.nth function, returns the first N-1 element in the list of L) Val record = List.nth (l,n-1): Sturecord (* Put the record in the The data is all read out, generating a string real.tostring () function to convert a real number to a string *) val str:string = "Name:" ^ (#name record) ^ ", Gaoshu:"^ (real.tostring (#gaoshu record)) ^ ", 中文版:" ^ (real.tostring (#english record)) ^ ", computer:" ^ (Real.tostring (#
Computer record) ^ ", Avage:" ^ (real.tostring (#avage Record)) in (* function return string *) str end; (* query records the first parameter: list, the position of the element in list starting from 0 The second parameter: LookFor string, indicating the student name to query, if not present, return negative one (to), the presence of the return position *) Fun Locaterecord (l,lookfo r:string) = Let (* list length, used to traverse the list *) val size = List.length (L)-1 (* recursive definition find element position the first parameter: list to find the second parameter: lookfor The first name to find the third parameter: the position of the element currently being processed *) (* always query to position 0, if not found, then return ~2,*) Fun Find (l,lookfor,~1) = | Find (L,lookfor,n) = Let (*list.nth function, returns the first N-1 element in the list of L) Val record = List.nth (l,n): Sturecord i
N (* If the record's Name property has the same value as LookFor, return n, otherwise continue querying the next position *) if lookfor= (#name record) then n else find (l,lookfor,n-1)
End IN (* Call the Find function, return element position *) find (l,lookfor,size) +1 end;
(* call *) val location:int = Locaterecord (record_list, "Tony");
Printrecord (record_list,location); Val location:int = Locaterecord (record_liSt, "Julie");
Printrecord (record_list,location); (* Change record *) val Renewrecord:sturecord = {name= "Lilei", gaoshu=99.0,english=99.0,computer=100.0,avage= (99.0+99.0+100.0)
/3.0}; Fun UpdateRecord (L,record:sturecord) = let val li = Nil:sturecord the list fun update ([],li) = Li | Update ((H:sturecord):: Bs,li) = if (#name h) = (#name record) then update (BS, (Record::li)) Else Update (BS,
(H::li))
In Update (l,[]) end;
Val Record_list:sturecord list = UpdateRecord (Record_list,renewrecord); (* Delete record *) Fun DeleteRecord (l,name_str:string) = let val li = nil fun Delete ([],li) = Li |
Delete ((H:sturecord):: Bs,li) = if (#name h) =name_str then delete (bs,li) Else Delete (Bs,h::li) in
Delete (l,[]) end;
Val Record_list:sturecord list = DeleteRecord (Record_list, "Adela");
(* Sort the list by average score *) Fun quick [] = [] |
Quick [X] = [x] | Quick (a::bs) = Let fun paritition (left,right,[]): Sturecord list = (quick left) @ (A::quick right) |paritition (LEFT,RIGHT,X::XS) = if (#avage x) >= (#avage a) then Paritition (X::LEFT,RIGHT,XS) Els
E paritition (Left,x::right,xs) in paritition ([],[],bs) end;
Val Record_list:sturecord list = quick (record_list);
(* Write back record to file *)
(* Open Write file *) val my_out = Textio.openout ("output.txt"); Fun WriteFile (Writerecod:sturecord) = let val str:string = "Name:" ^ (#name writerecod) ^ ", Gaoshu:" ^ (Real.tostring (#gao Shu writerecod) ^ ", 中文版:" ^ (real.tostring (#english writerecod)) ^ ", computer:" ^ (Real.tostring (#computer
Writerecod) ^ ", Avage:" ^ (real.tostring (#avage writerecod)) ^ "\ n" in Textio.output (MY_OUT,STR) end;
List.map WriteFile Record_list;
(* Close Write file *) Textio.closeout (my_out);
Data composition of Datas.txt
aaron,100,99,98
yao,100,100,97.5
adela,100,96,95
kitty,89,97,100
lucy,90,90,90
Lily, 80,90,85
alice,89,89,100
lilei,100,85,98
hanmeimei,100,100,100
tony,95,95,94
ford,97,80,80
fire,99,90,95