SML语言 形式语意学

(*
	定义记录结构
	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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值