scala习题(11)——操作符
来源:互联网 发布:模拟整容软件 编辑:程序博客网 时间:2024/06/15 09:50
scala操作符优先级
*/%
+-
:
<>
!=
&
^
|-
非操作符
最低优先级赋值操作符
从高到低优先级逐渐降低,同一层属同等优先级,按照从左到右的顺序进行计算(除了以冒号结尾的操作符和赋值操作符)
1.根据优先级规则,3+4 ->5 和 3 ->4+5是如何被求值的
(3+4 ->5)因为+号和->号的优先级在同一层次上(组合操作符按照组合中的最高级别操作符来定义优先级,+,-号在同一层,所以优先级一样),所以按照从左到右的运算方式来运算即为(7,5)
第二个算式存在问题,不能直接这么加减,因为元组和int相加时会先转换成字符串,而5的类型并不是字符串,直接repl中输入就会上报一个type missmatch的错误
2.BigInt类有一个pow方法,但没有用操作符字符。Scala类库的设计者为什么没有选用**(像Fortran那样)或者^(像Pascal那样)作为乘方操作符呢?
一般乘方的操作符是优于乘法操作的,如果使用**作为乘方的话,那么其优先级则与*相同,而如果使用^的话则属于非操作符,则优先级低于*操作。优先级都是有问题的。故没有使用这两种操作符
3.实现Fraction类,支持+*/操作。支持约分,例如将15/-6变为-5/2。除以最大公约数,像这样:
class Fraction(n:Int,d:Int){ private val num:Int = if(d==0) 1 else n * sign(d)/gcd(n,d); private val den:Int = if(d==0) 0 else d * sign(d)/gcd(n,d); override def toString = num + "/" + den def sign(a:Int) = if(a > 0) 1 else if (a < 0) -1 else 0 def gcd(a:Int,b:Int):Int = if(b==0) abs(a) else gcd(b,a%b) ...}
class Fraction(n:Int,d:Int){ private val num:Int = if(d==0) 1 else n * sign(d)/gcd(n,d); private val den:Int = if(d==0) 0 else d * sign(d)/gcd(n,d); override def toString = num + "/" + den def sign(a:Int) = if(a > 0) 1 else if (a < 0) -1 else 0 def gcd(a:Int,b:Int):Int = if(b==0) abs(a) else gcd(b,a%b) def +(other:Fraction):Fraction={ new Fraction((this.num*other.den+this.den*other.num),this.den*other.den); } def -(other:Fraction):Fraction={ new Fraction((this.num*other.den-this.den*other.num),this.den*other.den); } def *(other:Fraction):Fraction={ new Fraction((this.num*other.num),this.den*other.den); } def /(other:Fraction):Fraction={ new Fraction((this.num*other.den),this.den*other.num); } } object Fraction { def apply(n:Int,d:Int):Fraction={ new Fraction(n,d); } def unapply(input:Fraction):Option[(Int,Int)]={ if(input.den==0) None else Some((input.num,input.den)); } }
- 实现一个Money类,加入美元和美分字段。提供+,-操作符以及比较操作符==和<。举例来说,Money(1,75)+Money(0,50)==Money(2,25)应为true。你应该同时提供*和/操作符吗?为什么?
不需要提供,因为对于金额来说,乘除并没有意义
class Money(y:Int,f:Int){ private val yuan:Int= if(f<100&&f>=0) y else if(f>=100) y+f/100 else { if(abs(f)>=100) y-abs(f)/100 else y-1}; private val fen:Int=if(f<100&&f>=0) f else if(f>=100) f%100 else { if(abs(f)>=100) abs(f)/100*100+f else f+100}; def +(other:Money):Money={ new Money(this.yuan+other.yuan,this.fen+other.fen); } def -(other:Money):Money={ if(this>other){ new Money(this.yuan-other.yuan,this.fen-other.fen); }else{ println("not much money"); null } } def >(other:Money):Boolean={ if(this.yuan>other.yuan){ true; }else if(this.yuan<other.yuan){ false }else{ if(this.fen>other.fen) true else false; } } def <(other:Money):Boolean={ if(this.yuan<other.yuan){ true; }else if(this.yuan>other.yuan){ false }else{ if(this.fen>other.fen) false else true; } } override def toString()="yuan:"+yuan+" fen:"+fen; } object Money{ def apply(y:Int,f:Int):Money={ new Money(y,f); } }
- 提 供操作符用于构造HTML表格。例如:Table() | “Java” | “Scala” || “Gosling” | “Odersky” || “JVM” | “JVM,.NET”应产出:JavaScalaGosling…
注意操作符无论何时都是针对于对象来说的,所以要返回的数据只能是该对象
class Table{ var s:String=""; def |(txt:String):Table={ s=s+"<td>"+txt+"</td>"; this; } def ||(txt:String):Table={ s=s+"</tr>"+"<tr><td>"+txt+"</td>"; this; } override def toString="<table><tr>"+s+"</tr></table>"; } object Table{ def apply():Table={ new Table(); } }
6.提供一个ASCIIArt类,其对象包含类似这样的图形:
/_/\
( ’ ’ )
( - )
| | |
(|)
提供将两个ASCIIArt图形横向或纵向结合的操作符。选用适当优先级的操作符命名。纵向结合的实例
/_/\ —–
( ’ ’ ) / Hello \
( - ) < Scala |
| | | \ Coder /
(|) —–
class ASCIIArt(str:String){ var markstr:ArrayBuffer[ArrayBuffer[String]]=new ArrayBuffer[ArrayBuffer[String]](); if(str!=null){ str.split("[\r\n]+").foreach { line => var a=new ArrayBuffer[String]();a+=line;markstr+=a; } } override def toString()={ var s=""; markstr.foreach { s+=_.mkString+"\n"; } s; } def +(other:ASCIIArt)={ var Str=""; var j=0; for(i<- 0 until this.markstr.length){ if(i<=other.markstr.length){ Str=Str+markstr(i).mkString+other.markstr(i).mkString+"\n"; }else{ Str=Str+markstr(i).mkString+"\n"; } j=j+1; } if(j<other.markstr.length){ for(i<- j until other.markstr.length){ Str=Str+other.markstr(i).mkString+"\n"; } } new ASCIIArt(Str); } }
7.实现一个BigSequence类,将64个bit的序列打包在一个Long值中。提供apply和update操作来获取和设置某个具体的bit
class BigSequence{ var SeqNum=new Array[Int](64); for(i<- (0 until SeqNum.length)){ SeqNum(i)= -1; } def pack():Long={ SeqNum.filter(_ >= 0).mkString.toLong } } object BigSequence{ def apply(num:Int,input:BigSequence):Int={ input.SeqNum(num); } def apply(num:Int)={ val b = new BigSequence var i = 0 num.toString.foreach{ n=> b.SeqNum(i) = n.getNumericValue i+=1 } b } def update(num:Int,input:BigSequence,value:Int)={ input.SeqNum(num)=value; } }
8.提供一个Matrix类—你可以选择需要的是一个2*2的矩阵,任意大小的正方形矩阵,或m*n的矩阵。支持+和操作。操作应同样适用于单值,例如mat*2。单个元素可以通过mat(row,col)得到
class Matrix(row:Int=2,col:Int=2,content:Array[Int]){ private val rowIndex=row; private val colIndex=col; private val co:Array[Int]=if(content.length<row*col) { val s=for(i <- (0 until row*col)) yield { if(i<content.length){ content(i) }else 0 } s.toArray; }else{ val s = for(i <- (0 until row*col)) yield { content(i) } s.toArray } def +(other:Matrix):Matrix={ if((this.rowIndex==other.rowIndex)&&(this.colIndex == other.colIndex)){ val s=for(i<-(0 until this.co.length)) yield { this.co(i)+other.co(i); } new Matrix(rowIndex,colIndex,s.toArray); }else null; } def -(other:Matrix):Matrix={ if((this.rowIndex==other.rowIndex)&&(this.colIndex == other.colIndex)){ val s=for(i<-(0 until this.co.length)) yield { this.co(i)-other.co(i); } new Matrix(rowIndex,colIndex,s.toArray); }else null; } def *(other:Matrix):Matrix={ if(this.colIndex==other.rowIndex){ val s:Array[Int]=new Array[Int](this.rowIndex*other.colIndex); for(i<-(0 until this.rowIndex )){ for(j<- (0 until other.colIndex)){ var sum=0; for(m<-( 0 until this.colIndex)){ val e=this.co(i*this.colIndex+m) val d=other.co(m*other.colIndex+j) sum=sum+e*d; } s(i*this.rowIndex+j)=sum; } } new Matrix(this.rowIndex,other.colIndex,s) }else null } def *(mat:Int):Matrix={ val s=for(i<- (0 until this.co.length)) yield{ this.co(i)*mat; } new Matrix(this.rowIndex,this.colIndex,s.toArray); } def show()={ for(i<- (0 until this.co.length)){ print(co(i)+","); } } } object Matrix{ def apply(row:Int=2,col:Int=2,content:Array[Int])={ new Matrix(row,col,content:Array[Int]); } }
9.为RichFile类定义unapply操作,提取文件路径,名称和扩展名。举例来说,文件/home/cay/readme.txt的路径为/home/cay,名称为readme,扩展名为txt
def unapply(path:String)={ val pa=path.split("/"); val index=pa(pa.length-1).indexOf(".") Some((pa(pa.length-1).substring(0, index),pa(pa.length-1).substring(index+1,pa(pa.length-1).length()))); }
10.为RichFile类定义一个unapplySeq,提取所有路径段。举例来说,对于/home/cay/readme.txt,你应该产出三个路径段的序列:home,cay和readme.txt
def unapplyseq(path:String):Option[Seq[String]]={ Some(path.split("/")); }
9和10中unapply的使用方法,这里给个例子
val Fraction(r)=f; println(r); def unapply(input:Fraction):Option[(Int,Int)]={ if(input.den==0) None else Some((input.num,input.den)); }
- scala习题(11)——操作符
- 快学Scala习题解答—第十一章 操作符
- 快学Scala习题解答—第十一章 操作符
- 快学Scala习题解答—第十一章 操作符
- 《快学Scala》习题详解 第11章 操作符
- scala习题(十)——特质
- scala习题(十三)——集合
- 快学Scala学习笔记及习题解答(10-11特质与操作符)
- scala习题(12)——高阶函数
- scala习题(14)——模式匹配和样例类
- Scala 第十一章 操作符 and 习题答案
- 快学Scala习题解答—第三章 数组相关操作
- 快学Scala习题解答—第三章 数组相关操作
- 快学Scala习题解答—第三章 数组相关操作
- 快学Scala习题解答—第三章 数组相关操作
- scala习题八——继承
- scala习题九——文件和正则表达式
- 快学scala第十六章习题——XML处理
- ImmDisableIME在xp下的bug
- 在线聊天系统雏形总结
- android工程目录
- mysql安装
- 从抑郁中走出来
- scala习题(11)——操作符
- 失落的世纪致富经典》卷二:5如何将财富吸引到你身边
- 初学java感想
- myeclipse 各种错误
- 任正非“互联网思维”如是说
- 【python学习笔记】Eclipse+PyDev搭建Python开发环境
- Tomcat中的设计模式--外观模式(门店模式)
- 【UML】构件图和部署图
- 在Xcode7上实现真机调试