(*
定义记录结构
name 名字
gaoshu 高等数学
english 英语
computer 计算机
avage 平均分
*)
type StuRecord ={
name:string,
gaoshu:real,
english:real,
computer:real,
avage:real
};
(*打开文件,准备读取数据*)
val my_in = TextIO.openIn("datas.txt");
(*读出文件内的数据转化为字符串链表*)
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 是记录的条数
*)
val str_list = createStringList(str_list,12);
(*把字符串链表转化成记录链表*)
fun createRecordList (line_str:string) =
let
fun notc (c:char) =
fn c' =>
c=c'
val stuInfo = 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(stuInfo,1))))
val english_score : real = 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 = {name=name_stu,gaoshu=gaoshu_score,english=english_score,computer=computer_score,avage=avage_sroce}
in
recorda
end;
(*
List.map 对str_list链表的每个元素应用createRecordList函数
record_list 生成record链表
*)
(*
map 函数对列表进行遍历操作
*)
val record_list : StuRecord list = List.map createRecordList str_list;
(*关闭文件*)
TextIO.closeIn(my_in);
(*
增加记录
没有考虑有序增加,只是简单的加入到表头
*)
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;
(*
打印函数
第一个参数: list 列表
第二个参数: 需要打印的位置,如果是负一(~1)则打印"don't exist"表示记录不存在
*)
fun printRecord (l,~1) = "don't exist"
| printRecord (l,n:int) =
let
(*List.nth函数,返回L列表中的第n-1个元素*)
val record = List.nth(l,n-1) : StuRecord
(*把记录中的数据全部读出,生成一个字符串 Real.toString() 函数用来把一个实数转换成字符串*)
val str : string = "name:"^(#name record)^",Gaoshu:"^(Real.toString(#gaoshu record))^",English:"^(Real.toString(#english record))^",Computer:"^(Real.toString(#computer record))^",Avage:"^(Real.toString(#avage record))
in
(*函数返回字符串*)
str
end;
(*
查询记录
第一个参数:List 列表,list中元素的位置从0开始
第二个参数:lookfor 字符串,表示要查询的学生姓名,如果不存在,就返回负一(~1),存在则返回位置
*)
fun locateRecord (l,lookfor:string) =
let
(*列表长度,用来遍历列表*)
val size = List.length(l)-1
(*
递归定义查找元素位置
第一个参数:List 要查找的列表
第二个参数:lookfor 要查找的名字
第三个参数:当前正在处理元素的位置
*)
(*一直查询到位置0,如果没有找到,则返回~2,*)
fun find (l,lookfor,~1) = ~2
| find (l,lookfor,n) =
let
(*List.nth函数,返回L列表中的第n-1个元素*)
val record = List.nth(l,n) : StuRecord
in
(*如果record的name属性的值和lookfor相同,则返回n,否则继续查询下一个位置*)
if lookfor=(#name record) then n else find(l,lookfor,n-1)
end
in
(*调用find函数,返回元素位置*)
find(l,lookfor,size)+1
end;
(*调用*)
val location : int = locateRecord(record_list,"tony");
printRecord (record_list,location);
val location : int = locateRecord(record_list,"Julie");
printRecord (record_list,location);
(*
更改记录
*)
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 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);
(*
删除记录
*)
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");
(*
对链表按平均成绩排序
*)
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)
else paritition(left,x::right,xs)
in
paritition([],[],bs)
end;
val record_list : StuRecord list = quick(record_list);
(*
写回记录到文件
*)
(*打开写文件*)
val my_out = TextIO.openOut("output.txt");
fun writeFile (writeRecod:StuRecord) =
let
val str : string = "name:"^(#name writeRecod)^",Gaoshu:"^(Real.toString(#gaoshu writeRecod))^",English:"^(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;
(*关闭写文件*)
TextIO.closeOut(my_out);
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