Scala (day02)

/**
学习scala写递归函数
1.scala递归函数的返回值类型必须显示声明,不能用自动推断
2.写递归的技巧,掌握两个要素:要素①找出函数关系
要素②找出结束条件
3.scala递归函数的结束条件返回值必须要return关键字返回


*/

object Demo11 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  
  //--给定一个斐波那契数列
  //--2 3 5 8 13 21
//--目标是写一个递归函数,判断数列第n项的数字是多少
//-一函数关系:f(n)=f(n-1)+f(n-2)
//-–结束条件:f()=2 f(1)=3


	def f1(n:Int):Int={
		if(n==0){return 2}
		if(n==1){return 3}
		else f1(n-1)+f1(n-2)
	}                                         //> f1: (n: Int)Int
	
	f1(2)                                     //> res0: Int = 5
  
  
 //--2 3 4 9 16 81 .
//--编写递归函数f2(n) ,判断第n项的数字是多少
	def f2(n:Int):Int={
		if(n==0) return 2
		if(n==1) return 3
		else f2(n-2)*f2(n-2)
	}                                         //> f2: (n: Int)Int
	
	
	f2(5)                                     //> res1: Int = 81
  
  // --2 3 4 9 8 27 16 81 ...
//--编写递归函数f3(n),判断第n项的数字是多少

	def f3(n:Int):Int={
		if(n==0) return 2
		if(n==1) return 3
		if(n%2==0)  f3(n-2)*2
		else  f3(n-2)*3
	}                                         //> f3: (n: Int)Int
  
  f3(8)                                           //> res2: Int = 32
  
  
  //10-1  循环输出
  for(i<-0 to 9)println(10-i)                     //> 10
                                                  //| 9
                                                  //| 8
                                                  //| 7
                                                  //| 6
                                                  //| 5
                                                  //| 4
                                                  //| 3
                                                  //| 2
                                                  //| 1
       
   //=========================================
   //利用一个函数,n-1 遍历输出
   //方式0
   def f4(n:Int):Unit={
   		for(i<-0 to n-1)println(n-i)
   }                                              //> f4: (n: Int)Unit
  
  f4(10)                                          //> 10
                                                  //| 9
                                                  //| 8
                                                  //| 7
                                                  //| 6
                                                  //| 5
                                                  //| 4
                                                  //| 3
                                                  //| 2
                                                  //| 1
    //方式1
    for (i<-10 to 0 by -1) println(i)             //> 10
                                                  //| 9
                                                  //| 8
                                                  //| 7
                                                  //| 6
                                                  //| 5
                                                  //| 4
                                                  //| 3
                                                  //| 2
                                                  //| 1
                                                  //| 0
   //方式2
  for( i<-0 to 10 reverse) println(i)             //> 10
                                                  //| 9
                                                  //| 8
                                                  //| 7
                                                  //| 6
                                                  //| 5
                                                  //| 4
                                                  //| 3
                                                  //| 2
                                                  //| 1
                                                  //| 0
    
    //===================================================
    //扑克牌,确定抽出的一张是什么牌
    //红桃A-K 1-13 黑桃A-K 14-26 梅花A-K 27-39  方块A-K 40-52  大王 53 小王 54
		//生成一个数字---模拟,实际中只能确定剩余牌数
		var a1=scala.util.Random.nextInt(100)
                                                  //> a1  : Int = 95
    //模拟剩余和
    var num=0                                     //> num  : Int = 0
    var i=1                                       //> i  : Int = 1
		while(i<55) {
			num=num+i
			i+=1
		}
		//实际中应该是是确定了这个总和,去求a1
		println(num-a1)                   //> 1390
 
    def f5(n:Int):Unit={
    	var k1=n/13
    	var k2=n%13
    	if(n==53) println("dawang")
    	if(n==54) println("xiaowang")
    	
    	if(k1==1&&k2==0) println("red-K")
    	if(k1==0) println("red"+k2)
    	if(k1==2&&k2==0) println("black-K")
    	if(k1==1) println("black"+k2)
    	if(k1==3&&k2==0) println("mh-K")
    	if(k1==2) println("mh"+k2)
    	if(k1==4&&k2==0) println("fk-K")
    	if(k1==3) println("fk"+k2)
    	
    	
    }                                             //> f5: (n: Int)Unit
    f5(a1)
    
    
    
    
    ///===========
		//123456
		//214365
    //n为偶数
    //将左右两个数替换   1 2  -----2 1
    //方式1
    var arr=Array(1,2,3,4,5,6,7,8,9,10)           //> arr  : Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    val len=arr.length                            //> len  : Int = 10
    var ii=2                                      //> ii  : Int = 2
    var sum=""                                    //> sum  : String = ""
    while(ii<=len){
    	sum+=(arr(ii-1).toString())+(arr(ii-2).toString())
    	ii+=2
    }
    println(sum)                                  //> 21436587109
    	
    //方式2
    var array=Array(1,2,3,4,5,6)                  //> array  : Array[Int] = Array(1, 2, 3, 4, 5, 6)
    def resv(arr:Array[Int])={
    	for(i<-0 until(arr.length-1, 2)){
    		val t=arr(i)
    		arr(i)=arr(i+1)
    		arr(i+1)=t
    	}
    }                                             //> resv: (arr: Array[Int])Unit
    
    resv(array)
    array                                         //> res3: Array[Int] = Array(2, 1, 4, 3, 6, 5)
    
    
    //编写函数计算x的n次方,其中n是整数,要考虑等n是0,正偶数,正奇数,负数这几种情况。
    //比如当x=2时,此函数要算出2^4,2^3,2^0,2^(-1)对应的值
    
    def mi(x:Double,n:Int):Double={
    	if(n==0) return 1
    	else if(n>0&&n%2==0){
    		mi(x,n/2)*mi(x,n/2)
    	}else if(n>0&&n%2==1){
    		mi(x,n-1)*x
    	}else{
    		1/mi(x,-n)
    	}
    }                                             //> mi: (x: Double, n: Int)Double
    
    mi(2,3)                                       //> res4: Double = 8.0
    
    
    
    //
    val m2=Map("book"->10,"gun"->100,"ipad"->1000)//> m2  : scala.collection.immutable.Map[String,Int] = Map(book -> 10, gun -> 1
                                                  //| 00, ipad -> 1000)
				
		val a5=for((k,v)<-m2)yield{(k,v*0.9)}
                                                  //> a5  : scala.collection.immutable.Map[String,Double] = Map(book -> 9.0, gun 
                                                  //| -> 90.0, ipad -> 900.0)
				
		
    
    
    
    
    
    
    
    
    
    
    
    
}
import scala.collection.mutable._

/**
知识点
1.scala支持懒值机制,通过lazy关键字来声明
2.懒值的特点是声明时并不是马上赋值,被调用时才会赋值
3.注意:lazy只能修饰常量(val),不能修饰变量(var)

4.scala的集合(collection)类型包含如下的类型:Array , List, set,Map, Tuple, I
5.immutable---定长的概念:一经声明,长度不能增加(不能修改)|
6.mutable----变长的概念:声明之后,可以追加(长度可变)

**/

object Demo02 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  val v1=100                                      //> v1  : Int = 100
  lazy val v2=100                                 //> v2: => Int
  println(v2)                                     //> 100
  
  
  //申明一个定长的数组  赋值
  val a1=Array(1,2,3)                             //> a1  : Array[Int] = Array(1, 2, 3)
  
  //--声明一个定长为3的数组,没有赋值
  val a2=new Array(3)                             //> a2  : Array[Nothing] = Array(null, null, null)
  
  //申明一个边长数组并赋值
  val a3=scala.collection.mutable.ArrayBuffer(1,2,3,4)
                                                  //> a3  : scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
    
    
  val a4=ArrayBuffer(1,2,3,4)                     //> a4  : scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4)
  
  
  //通过下标操作数组
  a1(0)                                           //> res0: Int = 1
  
  a1(0)=10
  
  a1(0)                                           //> res1: Int = 10
  
  //变长数组追加数据
  a3.append(5)
  
  a3                                              //> res2: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 4, 5)
                                                  //| 
  
  val a5=Array(1,2,3,4,5,6)                       //> a5  : Array[Int] = Array(1, 2, 3, 4, 5, 6)
  
  //去除前三个元素,并返回一个新数组
  val r1=a5.take(3)                               //> r1  : Array[Int] = Array(1, 2, 3)
  val r2=a5.takeRight(2)                          //> r2  : Array[Int] = Array(5, 6)
  
 //取出数组的头一个元素.有别于take(1)
  val r3=a5.head                                  //> r3  : Int = 1
  
  val r4=a5.take(1)                               //> r4  : Array[Int] = Array(1)
  
  //删除前n个元素,将剩余元素返回到新数组中
  val r5=a5.drop(2)                               //> r5  : Array[Int] = Array(3, 4, 5, 6)
  
  val r6=a5.dropRight(2)                          //> r6  : Array[Int] = Array(1, 2, 3, 4)
  
  
  //取出末尾元素,有别于takeRight(1)
  val r7=a5.last                                  //> r7  : Int = 6
  
  val r8=a5.takeRight(1)                          //> r8  : Array[Int] = Array(6)
  
  //最大值
  val r9=a5.max                                   //> r9  : Int = 6
  
  //最小值
  val r10=a5.max                                  //> r10  : Int = 6
  
  //求和
  val r11=a5.sum                                  //> r11  : Int = 21
  
  //a5数组的均值
  //val r12=(a5.sum)/a5.length
  val r12=(a5.sum).toDouble/a5.length             //> r12  : Double = 3.5
  
  
  val a6=Array(1,1,2,3,3,4)                       //> a6  : Array[Int] = Array(1, 1, 2, 3, 3, 4)
  
  //去重
  val r13=a6.distinct                             //> r13  : Array[Int] = Array(1, 2, 3, 4)
  
  //
  val a7=Array(1,2,3)                             //> a7  : Array[Int] = Array(1, 2, 3)
  val a8=Array(3,4,5)                             //> a8  : Array[Int] = Array(3, 4, 5)
  //取交集,并将结果返回新的数组
  val r14=a7.intersect(a8)                        //> r14  : Array[Int] = Array(3)
  
  //并集---返回新数组
  val r15=a7.union(a8)                            //> r15  : Array[Int] = Array(1, 2, 3, 3, 4, 5)
  
  //取差集
  val r16=a7.diff(a8)                             //> r16  : Array[Int] = Array(1, 2)
  
  val r17=a8.diff(a7)                             //> r17  : Array[Int] = Array(4, 5)
  
  
  //val r18=a7.mkString
  //将数组中的元素以字符串返回,并指定分隔符
  val r18=a7.mkString(",")                        //> r18  : String = 1,2,3
  
  //反转
  val r19=a7.reverse                              //> r19  : Array[Int] = Array(3, 2, 1)
  
  //根据指定的匿名函数过滤,并返回新数组
  val r20=a7.filter{x=>x>1}                       //> r20  : Array[Int] = Array(2, 3)
  
  val a9=Array(14,16,22,25,30,40,18)              //> a9  : Array[Int] = Array(14, 16, 22, 25, 30, 40, 18)
  
  //计算出a9中成年人的年龄之和
  val r21=a9.filter{x=>x>=18}.sum                 //> r21  : Int = 135
  //r21.sum
  
  //要求统计未成年中最大的年龄
  
  val r22=a9.filter{x=>x<18}.max                  //> r22  : Int = 16
  
  //根据指定的匿名函数返回个数
  val r23=a9.count{x=>x>20}                       //> r23  : Int = 4
  
  val a10=Array(1,2,3,4)                          //> a10  : Array[Int] = Array(1, 2, 3, 4)
  val a11=Array(3,4,5,6)                          //> a11  : Array[Int] = Array(3, 4, 5, 6)
  
  //要求返回a10 a11中不重复的偶数个数
  
  a10.union(a11).distinct.count{x => x%2==0}      //> res3: Int = 3
  
  //指定函数,是否存在
  //返回true或false
  val r25=a10.exists{x=>x>5}                      //> r25  : Boolean = false
  
  //
  val a12=Array("1310","1311","13111")            //> a12  : Array[String] = Array(1310, 1311, 13111)
  //判断a12中是否存在非法的手机号----4位是正常
  
  val r26=a12.exists { x => x.length()!=4 }       //> r26  : Boolean = true
  
  
  val a13=Array(2,1,4,3,5)                        //> a13  : Array[Int] = Array(2, 1, 4, 3, 5)
  //--按指定的匿名函数条件排序,并将结果返回到新数组中
  //--升序
  val r27=a13.sortBy{num=>num}                    //> r27  : Array[Int] = Array(1, 2, 3, 4, 5)
  
  //降序
  val r28=a13.sortBy { num => num }.reverse       //> r28  : Array[Int] = Array(5, 4, 3, 2, 1)
  //降序
  val r29=a13.sortBy{num => -num}                 //> r29  : Array[Int] = Array(5, 4, 3, 2, 1)
  
  
  val a14=Array("tom 23","rose 18","jim 35","jary 20")
                                                  //> a14  : Array[String] = Array(tom 23, rose 18, jim 35, jary 20)
  //操作a14,按年龄升序
  
  val r30=a14.sortBy { x => x.split(" ")(1).toInt }
                                                  //> r30  : Array[String] = Array(rose 18, jary 20, tom 23, jim 35)
  
  //操作a14  取出年龄最大的两个人的数据
  
  val r31=a14.sortBy { x => x.split(" ")(1).toInt }.takeRight(2)
                                                  //> r31  : Array[String] = Array(tom 23, jim 35)
  
  val a15=Array(1,2,3,4)                          //> a15  : Array[Int] = Array(1, 2, 3, 4)
  
  //--最重要的方法,映射方法,作用是将集合中的元素从一个形式转变到另一个形式
  //--然后将结果返回到新的数组中
	//改变元素形式, 元素个数不变
  val r32=a15.map { num => num*2 }                //> r32  : Array[Int] = Array(2, 4, 6, 8)
  
  
  val r33=a15.map { num => num.toString() }       //> r33  : Array[String] = Array(1, 2, 3, 4)
  
  
  val a16=Array("tom M 23","rose F 29 20","jim M 35")
                                                  //> a16  : Array[String] = Array(tom M 23, rose F 29 20, jim M 35)
  
  //操作a16 返回数组只含有姓名信息
  val r34=a16.map { line => line.split(" ")(0) }  //> r34  : Array[String] = Array(tom, rose, jim)
  
  //操作a16 ,统计年龄最大的前两个人的年龄之和
  val r35=a16.map { line => line.split(" ")(2).toInt }.sortBy { age => age }.takeRight(2).sum
                                                  //> r35  : Int = 64
  
  val a17=Array(1,2,3,4)                          //> a17  : Array[Int] = Array(1, 2, 3, 4)
  
 // --reduce规约方法,底层是一种迭代方法
 // --①次迭代a=1 b=2 a+b=3
 // --②次迭代 a=3 b=3 a+b=6
 // --③次迭代 a=6 b=4 a+b=10
  
  val r36=a17.reduce{(a,b)=>a+b}                  //> r36  : Int = 10
  
  //计算1-6的阶乘
  //val r37=(1 to 6).reduce{(a,b)=>a*b}
  val r37=1 to 6 reduce{(a,b)=>a*b}               //> r37  : Int = 720
  
  
  
  
  
  
  
  
  
  
  
}
/**

学习List
Array和List通用而且重要的方法
1.take
2.takeRight
3.drop
4.dropRight
5.head
6.last
7.max
8.min
9.sum
10.mkstring
11.intersect
12.union
13.diff
14.filter
15.sortBy
16.count
17.exists -
18.map
19.reduce
20.distinct
21.foreach

再重点掌握:1.filter .sortBy 3.map 4.reduce

*/

object Demo03 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  
  //申明一个定长list,并赋值
  val l1=List(1,2,3,4)                            //> l1  : List[Int] = List(1, 2, 3, 4)
  
  //申明一个定长list  指定长度
  val l2=List[Int](3)                             //> l2  : List[Int] = List(3)
  
  //申明变长list
  val l3=scala.collection.mutable.ListBuffer(1,2,3,4)
                                                  //> l3  : scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
  l3.foreach { x => println(x) }                  //> 1
                                                  //| 2
                                                  //| 3
                                                  //| 4
  
  //基于某一个list 添加元素,返回一个新list
  val l4=l1.::(5)                                 //> l4  : List[Int] = List(5, 1, 2, 3, 4)
  
  
  //-掌握类型间转换技巧
  //--比如某一种集合类型没有指定的方法,可以尝试先转变为Array或List来处理
  val l5=List(1,1,2,2,3)                          //> l5  : List[Int] = List(1, 1, 2, 2, 3)
  
  l5.toArray.distinct.toList                      //> res0: List[Int] = List(1, 2, 3)
  
  
  

  
  
  
}
/**
学习set
*/

object Demo04 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  //--声明定长set
  val s1=Set(1,1,2,3,3)                           //> s1  : scala.collection.immutable.Set[Int] = Set(1, 2, 3)
  
  //申明变长set
  val s2=scala.collection.mutable.Set(1,2,3,4)    //> s2  : scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4)
  
  val s3=Set(1,2,3)                               //> s3  : scala.collection.immutable.Set[Int] = Set(1, 2, 3)
  
  val s4=Set(3,4,5)                               //> s4  : scala.collection.immutable.Set[Int] = Set(3, 4, 5)
  
  //取交集
  s3.intersect(s4)                                //> res0: scala.collection.immutable.Set[Int] = Set(3)
  s3&s4                                           //> res1: scala.collection.immutable.Set[Int] = Set(3)
  
  //取并集
  s3.union(s4)                                    //> res2: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
  s3++s4                                          //> res3: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
  
  //取差集
  s3.diff(s4)                                     //> res4: scala.collection.immutable.Set[Int] = Set(1, 2)
  s3&~s4                                          //> res5: scala.collection.immutable.Set[Int] = Set(1, 2)
  
  
  
  
  
  
  
  
}
/**
学习map

*/

object Demo05 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  //申明一个定长map
  val m1=Map("tom"->23,"rose"->30)                //> m1  : scala.collection.immutable.Map[String,Int] = Map(tom -> 23, rose -> 30
                                                  //| )
  //申明变长map。可以追加
  val m2=scala.collection.mutable.Map("tom"->23,"rose"->30)
                                                  //> m2  : scala.collection.mutable.Map[String,Int] = Map(rose -> 30, tom -> 23)
                                                  //| 
  
  //通过key取value
  m1.apply("tom")                                 //> res0: Int = 23
  //可以省略apply
  m1("tom")                                       //> res1: Int = 23
  //不存在会报错,用get方法返回none
  //m1("tom1")
  
  //通过get取值,返回一个option类型
  // --option有两个子类:Some None
  // --如果指定的key有value,就将value封装到Some里
  //--如果不存在指定的key,则返回None
  m1.get("tom")                                   //> res2: Option[Int] = Some(23)
  m1.get("tom1")                                  //> res3: Option[Int] = None
  
  //通过getOrElse获取some里的值
  //返回是none,返回指定的默认值
  m1.get("tom").getOrElse(0)                      //> res4: Int = 23
  m1.get("tom1").getOrElse(0)                     //> res5: Int = 0
  
  //变长map做追加
  m2+=("jim"->35,"jary"->40)                      //> res6: Demo05.m2.type = Map(jary -> 40, jim -> 35, rose -> 30, tom -> 23)
  
  
  //返回map中key的迭代器
  m1.keys                                         //> res7: Iterable[String] = Set(tom, rose)
  
  //返回map中value的迭代器
  m1.values                                       //> res8: Iterable[Int] = MapLike(23, 30)
  
  //掌握case匹配的使用方法
  val r1=m1.filter{case(k,v)=>v>25}               //> r1  : scala.collection.immutable.Map[String,Int] = Map(rose -> 30)
  
  
  //操作m1,将每个人的年龄加10
  val r2=m1.map{case(k,v)=>(k,v+10)}              //> r2  : scala.collection.immutable.Map[String,Int] = Map(tom -> 33, rose -> 40
                                                  //| )
  
  //--操作Map类型时,如果只针对Map的Value做映射
  //--可以用mapvalues方法
  val r3=m1.mapValues { x => x+10 }               //> r3  : scala.collection.immutable.Map[String,Int] = Map(tom -> 33, rose -> 40
                                                  //| )
  
  m1.foreach{x=>println(x)}                       //> (tom,23)
                                                  //| (rose,30)
  m1.foreach{case(k,v)=>println(k)}               //> tom
                                                  //| rose
  
  
  val r4=m1.toArray                               //> r4  : Array[(String, Int)] = Array((tom,23), (rose,30))
  
  val r5=m1.toList                                //> r5  : List[(String, Int)] = List((tom,23), (rose,30))
  
  
  
  
  
  
}
/**
学习Tuple(元组)类型。这种类型最常用,最灵活的数据类型
通过(()声明的数据,就是一个元组类型

*/

/**
学习Tuple(元组)类型。这种类型最常用,最灵活的数据类型
通过(()声明的数据,就是一个元组类型

*/

object Demo06 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  //申明一个包含四个元素的数组
  val t1=(1,2,3,4)                                //> t1  : (Int, Int, Int, Int) = (1,2,3,4)
  
  val t2=(1,"hello",Array(1,2,3,4),List(3,4))     //> t2  : (Int, String, Array[Int], List[Int]) = (1,hello,Array(1, 2, 3, 4),List
                                                  //| (3, 4))
  
  //元组取值,通过._ 下标取值
  t2._2                                           //> res0: String = hello
  
  
  val t3=((1,2),Array(3,4,5),(6,7,8))             //> t3  : ((Int, Int), Array[Int], (Int, Int, Int)) = ((1,2),Array(3, 4, 5),(6,7
                                                  //| ,8))
  
  //操作t3,取出7
  t3._3._2                                        //> res1: Int = 7
  
  //操作t3  取出数字5
  t3._2(2)                                        //> res2: Int = 5
  
  
  val m1=Map("tom"->23,"rose"->30)                //> m1  : scala.collection.immutable.Map[String,Int] = Map(tom -> 23, rose -> 30
                                                  //| )
  
  
  //过滤m1,过滤出>25的数据。两种方式
  m1.filter{case(k,v) => v>25}                    //> res3: scala.collection.immutable.Map[String,Int] = Map(rose -> 30)
  m1.filter{x=>x._2>25}                           //> res4: scala.collection.immutable.Map[String,Int] = Map(rose -> 30)
  
  //m1.map{case(k,v)=>if(v>25)println(k,v)}
  //m1.mapValues { x => if(x>25)println(x) }
	//for((k,v)<-m1)yield(k,v>25)
  
  
  val l1=List(("b",3),("a",4),("c",1),("d",2))    //> l1  : List[(String, Int)] = List((b,3), (a,4), (c,1), (d,2))
  
  
  //要求操作l1,根据字母升序排序
  
  l1.sortBy{line => line._1}                      //> res5: List[(String, Int)] = List((a,4), (b,3), (c,1), (d,2))
  
  
  l1.sortBy{line => -line._2}                     //> res6: List[(String, Int)] = List((a,4), (b,3), (d,2), (c,1))
  
  
  l1.sortBy{case(x,y)=> -y}                       //> res7: List[(String, Int)] = List((a,4), (b,3), (d,2), (c,1))
  
  
  
  val l2=List(("hello",1),("hello",1),("world",1),("hello",1))
                                                  //> l2  : List[(String, Int)] = List((hello,1), (hello,1), (world,1), (hello,1))
                                                  //| 
  //操作l2  返回新的lsit  (hello,world)
  
  
  l2.map{x=> x._1}.distinct                       //> res8: List[String] = List(hello, world)
  
  l2.map{case(x,y)=> x}.distinct                  //> res9: List[String] = List(hello, world)
  
  
  val l3=List(("tom","M",15000),("rose","F",16000),("jim","M",10000),("jary","M",12000))
                                                  //> l3  : List[(String, String, Int)] = List((tom,M,15000), (rose,F,16000), (ji
                                                  //| m,M,10000), (jary,M,12000))
  
  //统计出男性薪资最高的前两名的薪资和
  
  l3.filter{x=> x._2=="M"}.sortBy{x=> x._3}.takeRight(2).map{x=> x._3}.sum
                                                  //> res10: Int = 27000
  val l4=List("hello world","hello hadoop","hello world")
                                                  //> l4  : List[String] = List(hello world, hello hadoop, hello world)
  
  l4.map { x => x.split(" ") }                    //> res11: List[Array[String]] = List(Array(hello, world), Array(hello, hadoop)
                                                  //| , Array(hello, world))
  //扁平化map,改变元素的形式,也改变元素个数
  //一般的使用场景是读取文件后,将每一行中的数据拿到
  l4.flatMap { x => x.split(" ")}                 //> res12: List[String] = List(hello, world, hello, hadoop, hello, world)
  
  
  val l5=List("hello","hello","world","hello","worl")
                                                  //> l5  : List[String] = List(hello, hello, world, hello, worl)
  
  //按照指定的匿名函数规则做分组
  //--返回的是一个Map(key , value)
 //--key是分组字段,value是相同数据组成的List
  val r11=l5.groupBy { x => x }                   //> r11  : scala.collection.immutable.Map[String,List[String]] = Map(worl -> Li
                                                  //| st(worl), world -> List(world), hello -> List(hello, hello, hello))
  
  val l6=List(("bj",1),("sh",2),("bj",3),("sh",4))//> l6  : List[(String, Int)] = List((bj,1), (sh,2), (bj,3), (sh,4))
  
  //操作l6,按地址分组
  val r12=l6.groupBy{x=> x._1}                    //> r12  : scala.collection.immutable.Map[String,List[(String, Int)]] = Map(bj 
                                                  //| -> List((bj,1), (bj,3)), sh -> List((sh,2), (sh,4)))
  val l7=List("hello world hadoop","hello world","hello hadoop")
                                                  //> l7  : List[String] = List(hello world hadoop, hello world, hello hadoop)
  
  //--统计出l7中每个单词出现的频次
	//--比如最后的结果:( hello,3 ) (world,2)(hadoop,2)
  
  val r13=l7.flatMap { line => line.split(" ") }.groupBy { line => line }.toList.map{case(x,y)=>(x,y.count { x => x==x })}
                                                  //> r13  : List[(String, Int)] = List((hadoop,2), (world,2), (hello,3))
  
  val r14=l7.flatMap { line => line.split(" ") }.groupBy { line => line }.mapValues { x => x.size }.toList
                                                  //> r14  : List[(String, Int)] = List((hadoop,2), (world,2), (hello,3))
  
  
  val r15=l7.flatMap { _.split(" ") }.groupBy { line => line }.map{case(k,v)=> (k,v.size)}.toList
                                                  //> r15  : List[(String, Int)] = List((hadoop,2), (world,2), (hello,3))
  
  //接着往下写,实现单词频次统计,不用使用size和length方法
  val r16=l7.flatMap { x => x.split(" ") }.map { x => (x,1) }.groupBy{x=> x}.map{case(k,v)=> (k,v.count{v=> v==v})}
  .map{case(k,v)=> (k._1,v)}                      //> r16  : scala.collection.immutable.Map[String,Int] = Map(hadoop -> 2, world 
                                                  //| -> 2, hello -> 3)
  
  l7.flatMap { x => x.split(" ") }.map { x => (x,1) }.groupBy{x=> x._1}.mapValues{x=>x.map{x=> x._2}.sum}.toList
                                                  //> res13: List[(String, Int)] = List((hadoop,2), (world,2), (hello,3))
  //化简
  l7.flatMap {_.split(" ") }.map { (_,1) }.groupBy{_._1}.mapValues{_.map{_._2}.sum}.toList
                                                  //> res14: List[(String, Int)] = List((hadoop,2), (world,2), (hello,3))
  
}
object Demo07 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  
  
  
  
  
  
  
  
  val p1=new Person("tom",23)                     //> p1  : Person = Person@7a79be86
  //辅助构造
  val p2=new Person("rose")                       //> p2  : Person = Person@34ce8af7
  val p3=new Person(19)                           //> p3  : Person = Person@b684286
  val p4=new Person                               //> p4  : Person = Person@880ec60
	//p1.setName("tom")
	//p1.setAge(18)
	p1.getName()                              //> res0: String = tom
	p1.getAge()                               //> res1: Int = 23
	p2.getName()                              //> res2: String = rose
	p3.getAge()                               //> res3: Int = 19
  //p1.say()
	


	//静态方法调用
	Util.sleep()                              //> Zzz
	
	//Person类的静态方法使用
	Person.speak()
	
	
	//
	val item1=Item("tom",13)                  //> item1  : Item = Item(tom,13)
	val item2=Item                            //> item2  : Item.type = Item
	println(item1)                            //> Item(tom,13)
	
	
	
	
	
	
	
	
	
	
}
/**
 * 
 * 1.scala的trait类比于java的Interface
 * 2.trait(特质)  可以定义抽象方法
 * 3.不同在于scala的特质还可以定义普通方法,这种设计机制的目的是让一个类实现多继承的效果(即把trait当做抽象类来处理)

 * 
 * 
 * 
 * 
 * 
 * 
 */

trait Dance {
  
  
  def baLei():Int
  
  def tiTa():String
  
  //普通方法
  def floor()={}
}


trait Drive {
  def piaoyi():Unit
  
  def stop():String
}

/**
 * 知识点
 * 1.通过case关键字来定义一个样列类
 * 2.case class必须声明一个主构造器
 * 3.当声明一个主构造器后,case class会默认声明一个空的辅助构造器
 * 4.case class 不需要New就可以创建类的实例对象
 * 5.case class 默认实现了tostring方法
 * 6.case class默认混入了序列化特质
 * 
 * 
 * 
 * 
 */
case class Item(val name:String,val age:Int) {
  
  
  
  
}
/**
 * 1.继承用extends
 * 2.混入特质用with
 * 3.scala是单继承,多混入
 * 4.scala要求必须有而且仅有一个extends关键字
 * 5.scala的序列化特质 Serializable
 * 
 */

 

//class LiuTeacher extends Teacher with Dance with Drive {
	class LiuTeacher  extends Dance with Drive with Serializable{
  def makeNote(line: String): String = {
    ???
  }

  def teach(): Unit = {
    ???
  }
  
  
//  override def speak()={
//    
//  }

  def baLei(): Int = {
    ???
  }

  def tiTa(): String = {
    ???
  }

  def piaoyi(): Unit = {
    ???
  }

  def stop(): String = {
    ???
  }
}

/** 
 * 知识点
 * 1.scala同java,通过class关键字来定义类
 * 2.scala class可以定义成员变量和成员方法
 * 3.scala class也是通过New来创建类的对象
 * 4.默认的访问权限是public。此外可以通过private或者protected来修饰
 * 5.scala class的方法支持重写和重载,定义同java
 * 6.scala class有一个主构造器,可以有多个辅助构造器
 * 7.scala class只有一个主构造器,在类上声明
 * 
 * 
 *  */
class Person(v1:String,v2:Int) {
  
  
  //定义成员变量
  //习惯定义成员变量时,附一个初始的变量值
  private var name=v1
  private var age=v2
  
  //辅构造器--只接受姓名
  //要求:辅助构造器中必须调用本类的其他构造器
  def this(v1:String){
    this(v1,0)
  }
  
  def setName(name:String)={
    this.name=name
    
  }
  
  //两个构造器  一个是只接受年龄,另一个是空
  //只接受年龄构造器
  def this(v2:Int){
    this("",v2)
  }
  //空构造器
  def this(){
    this("",0)
  }
  def getName()={
    this.name
    
  }
  
  
   def setAge(age:Int)={
    this.age=age
    
  }
  def getAge()={
    this.age
    
  }
   def say()={
    
    println("hello")
  }
}

object Person{
  //定义静态方法
  def speak()={
    
  }
}
/**
 * 知识点
 * 1.scala同java,通过extends来继承父类
 * 2.scala同java,单继承
 * 3.如果重写的方法是一个普通方法,需要加override
 * 4.如果重写的方法是一个抽象方法,不需要加overridel
 * 
 * 
 *  */

class Student extends Person{
  override def say()={
    
  }
  
}

/**
 * 知识点
 * 1.scala同java,通对abstract来定义一个抽象类
 * 2.s.cala的抽象类中可以定义抽象方法和普通方法
 * 3.抽象方法没有方法体{}
 * 
 * 
 *  */
abstract class Teacher {
  
  
  //抽象
  def makeNote(line:String):String
  //抽象
  def teach():Unit
  //普通方法
  def speak()={}
}

/**
 * 知识点
 * 1.scala object单例对象类。
 * 2.在scala object里定义的变量和方法都是静态的
 * 3.scala object不能New
 * 4.如果要写main方法,需要在单例对象类中来写
 * 5.如果要为一个类(class)添加静态成员或方法,方式是:在class的同一个文件下,
 * 创建一个同名的object类。此时,class和object产生了绑定关系
 * 
 * class称为object的伴生类
 * object成为class的伴生对象
 * 
 * 
 * 
 */
object Util {
  
  
  
  def sleep()={
    println("Zzz")
  }
  
  
  
  def main(args: Array[String]): Unit = {
    val a1=Array(1,2,3,4)
    a1.foreach { x => println(x) }
    
  }
}

练习

1."Hello""World"进行拉链操作,会产生什么结果?

2.编写函数values(fun:(Int)=>Int,low:Int,high:Int),该函数输入和输出一个集合,对应给定区间内给定函娄入和输出。比如,
-5,-4,-3,-2,-1,0,1,2,3,4,5
values(x=>x*x,-5,5)应该产出一个对偶的集合(-5,25),(-4,16),(-3,9),...(3,9),(5,25)

3.如何用reduce得到数组中的最大元素?Array(1,2,3,4,5)
不用使用max
4.to和reduceLeft实现阶乘函数比如算1~10的阶乘结果

5.编写函数largest(fun:(Int)=>Int,inputs:Seq[Int]),输出在给定输入序列中给定函数的最大值。举例来说,
largest(x=>10*x-x*x,1 to 10)应该返回251=>x=>10*x-x*x=9
2=>x=>10*x-x*x=16……

返回其中的最大值25

6.修改前一个函数,返回最大的输出对应的输入。举例来说,largestAt(fun:(Int)=>Int,inputs:Seq[Int])该返回5

7.编写一个函数,接收一个整数数组(Array[Int]),产出一个新的数组。
包含原数组中的所有正值,以原有顺序排列,之后的元素是所有零或负值,以原有顺序排列。

比如:Array(4,-2,0,-3,0,1,5),处理后的结果是:Array ( 4 ,1,5,0,0,-2,-3 )


//import scala.collection.mutable._
object Demo08 {
  println("Welcome to the Scala worksheet")       //> Welcome to the Scala worksheet
  
  val s1="hello"                                  //> s1  : String = hello
  val s2="world"                                  //> s2  : String = world
  //  --拉链操作,将对应项的数据放在一起
  --进行拉链操作时,元素个数尽量一致
  s1 zip s2                                       //> res0: scala.collection.immutable.IndexedSeq[(Char, Char)] = Vector((h,w), (e
                                                  //| ,o), (l,r), (l,l), (o,d))
  val a1=Array(1,2,3,4)                           //> a1  : Array[Int] = Array(1, 2, 3, 4)
  val a2=Array("a","b","c","d")                   //> a2  : Array[String] = Array(a, b, c, d)
  a1 zip a2                                       //> res1: Array[(Int, String)] = Array((1,a), (2,b), (3,c), (4,d))
  
  
  //可以在这里导包
  import scala.collection.mutable._
  
  
  
  def f1(f:(Int)=>Int,start:Int,end:Int)={
  		val result=ListBuffer[(Int,Int)]()
  		for(i<-start to end ){
  			result.append((i,f(i)))
  		}
  		result
  }                                               //> f1: (f: Int => Int, start: Int, end: Int)scala.collection.mutable.ListBuffer
                                                  //| [(Int, Int)]
  
        
   f1(x=>x*x,-5,5)                                //> res2: scala.collection.mutable.ListBuffer[(Int, Int)] = ListBuffer((-5,25), 
                                                  //| (-4,16), (-3,9), (-2,4), (-1,1), (0,0), (1,1), (2,4), (3,9), (4,16), (5,25))
                                                  //| 
    
//--1次a=2 b=1
//result=2
// --2次a=2 b=5
//result=5
// --3次a=5 b=4
//result=5
    
   val a3=Array(2,1,5,4,3)                        //> a3  : Array[Int] = Array(2, 1, 5, 4, 3)
   a3.reduce{(a,b)=> if(a>b) a else b}            //> res3: Int = 5
    
    
    
    
   1 to 10 reduce{_*_}                            //> res4: Int = 3628800
   
   
   
   def f2(f:(Int)=>Int,inputs:Seq[Int])={
   			val s=inputs.reduceRight{(a,b)=> if(f(a)>f(b)) a else b}
   			f(s)
   }                                              //> f2: (f: Int => Int, inputs: scala.collection.mutable.Seq[Int])Int
   
   f2(x=>10*x-x*x,1 to 10 toArray)                //> res5: Int = 25
   
   
   
   def f3(f:(Int)=>Int,inputs:Seq[Int])={
   			val s=inputs.reduce{(a,b)=> if(f(a)>f(b)) a else b}
   			s
   }                                              //> f3: (f: Int => Int, inputs: scala.collection.mutable.Seq[Int])Int
   
   f3(x=>10*x-x*x,1 to 10 toArray)                //> res6: Int = 5
   
   
   val a4=Array(1,2,0,0,5,-3,-2,4,-6)             //> a4  : Array[Int] = Array(1, 2, 0, 0, 5, -3, -2, 4, -6)
   
   def f4(arr:Array[Int])={
   		val arr1=for(i<-arr;if i>0)yield{i}
   		val arr2=for(i<-arr;if i==0)yield{i}
   		val arr3=for(i<-arr;if i<0)yield{i}
   		
   		
   		arr1.union(arr2).union(arr3)

   		
   }                                              //> f4: (arr: Array[Int])Array[Int]
   
   f4(a4)                                         //> res7: Array[Int] = Array(1, 2, 5, 4, 0, 0, -3, -2, -6)
   
   

   def f5(a:Int,b:Int):Option[Int]={
   			if(b!=0){
   				Some(a/b)
   			}else{
   				None
   			}
   }                                              //> f5: (a: Int, b: Int)Option[Int]
   
   f5(5,1)                                        //> res8: Option[Int] = Some(5)
   f5(5,1).getOrElse(100)                         //> res9: Int = 5
   
   
}

思考

有一个文件,存储了40亿个整型数字(都不重复)要求找出哪些数字没有出现过,而且内存不能超过1GB
Int类型的范围将近43亿,所以文件中40亿,肯定是有些数字没有出现过。
如果用整型数组存40亿个数,内存占用=160亿B~15GB不满足要求,所有想办法解决。
不能使用大数据框架

题目说明
40亿个非负整数中找到没出现的数
题目要求
最多使用1GB内存
实现思路
32位无符号整数的范围是0~4294967295,现在有一个正好包含40亿个无符号整数的文件,所以在
整个范围中必然有没出现过的数。可以使用最多1GB的内存,怎么找到所有没出现过的数?
如果用整数数组来保存出现过的数,那么如果40亿个数都不同,存一个32位整数需要4B,所以最差
情况下需要40亿×4B=160亿字节,大约需要16GB的空间,这是不符合要求的。

解决方式

package cn.bit;

import java.util.BitSet;

import org.junit.Test;

public class TestDemo {
	@Test
	public void bitSetTest(){
		//常见一个比特类型数组
//		BitSet bs=new BitSet();
		BitSet bs=new BitSet( Integer.MAX_VALUE);

		//1010 0101

		//--处理思路,将出现的数字对应的位进行设置,比如100出现过,则set(100)
		//--最终,将出现的40亿数字用bitset存完之后,再次遍历,出现False对应的位数字
		//--就是没有出现过的

		
		bs.set(0);
		bs.set(2);
		bs.set(5);
		bs.set(7);

		for (int i = 0; i < bs.length(); i++) {
			System.out.println(bs.get(i)==false?bs.get(i)+"###未出现"+i:"");
		}
		
		
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值