package com.datacrafts.digitalevers.sparseMatrix
import java.io.FileWriter
import com.datacrafts.digitalevers.curry.FileReader.{closeStream, getLines, isReadable}
import com.google.gson.Gson
import scala.collection.mutable.ArrayBuffer
/**
* 此例程提供Scala对稀疏矩阵进行压缩解压模拟的操作方法
* 通用方式
*/
object normal{
implicit val filePath = ""
def main(args: Array[String]): Unit = {
/*var test = Array.ofDim[Int](11,3)
test(5)(2) = 11
test(3)(1) = 5
var resJson = zipMatrix(test)(checkMatrix)("json.txt")*/
val arr = unzipMatrix("json.txt")
}
/**
* 压缩稀疏矩阵并将其保存到文件中
*/
def zipMatrix(inArray:Array[Array[Int]])(check:(Array[Array[Int]])=>Array[Int])(implicit filePath:String) = {
val newMatrix = ArrayBuffer[Array[Int]]()
val res:Array[Int] = check(inArray)
newMatrix.append(Array(res(0),res(1),0))
for(i <- 0 until inArray.length){
for(j <- 0 until inArray(i).length){
if(inArray(i)(j) != 0){
newMatrix.append(Array(i,j,inArray(i)(j)))
}
}
}
//print(filePath)
val arr = newMatrix.toArray //ArrayBuffer -> Array -> json
val gson = new Gson()
val json = gson.toJson(arr)
if(filePath.isEmpty == true){
json
} else {
save2File(filePath,json)
}
}
/**
* 从文件中读取数据并解压成稀疏矩阵
*/
def unzipMatrix(filePath:String) = {
val content = getLines(filePath) (isReadable) (closeStream)
if(content == ""){
throw new Exception("文件内容为空")
}
val res = ArrayBuffer[Array[Int]]()
val gson = new Gson()
val arr = gson.fromJson(content,classOf[Array[Array[Int]]])
for(i <- 0 until arr.length){
if(i == 0){
for(j <- 0 until arr(i)(0)){
res.append(Array.ofDim[Int](arr(i)(1)))
}
} else {
res(arr(i)(0))(arr(i)(1)) = arr(i)(2)
}
}
res.toArray
}
/**
* 检测数组的容积(长和宽)
* @param inArray
* @return
*/
def checkMatrix(inArray:Array[Array[Int]]):Array[Int] = {
if(inArray.length > 0){
val i = inArray.length
val j = inArray(0).length
Array(i,j)
} else {
Array(0,0)
}
}
/**
* 保存字符串到文件中
* @param filePath 文件路径
* @param content 需要保存的字符内容
* @return 保证成功 true 保存失败 false
*/
def save2File(filePath:String,content:String): Boolean = {
try {
val out = new FileWriter(filePath, true)
out.write(content)
out.close()
true
} catch {
case ex: Throwable => {
false
}
}
}
////////////////
}
下面是泛型方式,在开发泛型方式的时候有一个小插曲
最开始使用Play Framework框架中的json解析库(play.api.libs.json)无法解析泛型的数组结构,更换到gson解析库,便可正常解析
package com.datacrafts.digitalevers.sparseMatrix
import com.datacrafts.digitalevers.curry.FileReader.{closeStream, getLines, isReadable}
import com.datacrafts.digitalevers.sparseMatrix.normal.{save2File, unzipMatrix}
import com.google.gson.Gson
import scala.collection.mutable.ArrayBuffer
/**
* 此例程提供Scala对稀疏矩阵进行压缩解压模拟的操作方法
* 泛型方式
*/
object generic{
implicit val filePath = ""
def main(args: Array[String]): Unit = {
var test = Array.ofDim[Double](11,3)
test(5)(2) = 11.1
test(3)(1) = 5.2
var res = zipMatrix(test)(checkMatrix)("json_generic.txt")
val arr = unzipMatrix("json_generic.txt")
for(line <- arr){
for(elem <- line){
print(elem.toString + " ")
}
println()
}
}
/**
* 压缩稀疏矩阵并将其保存到文件中
*/
def zipMatrix[T](inArray:Array[Array[T]])(check:(Array[Array[T]])=>Array[Int])(implicit filePath:String) = {
val newMatrix = ArrayBuffer[Array[Any]]()
val res:Array[Int] = check(inArray)
newMatrix.append(Array(res(0),res(1),0))
for(i <- 0 until inArray.length){
for(j <- 0 until inArray(i).length){
if(inArray(i)(j) != 0){
newMatrix.append(Array(i,j,inArray(i)(j)))
}
}
}
val arr = newMatrix.toArray
val gson = new Gson()
val json = gson.toJson(arr)
if(filePath.isEmpty == true){
json
} else {
save2File(filePath,json)
}
}
/**
* 因为泛型的压缩数组数据类型不确定
* 所以这个隐式函数提供给 unzipMatrix 作隐式类型转换
* @param in
* @return
*/
implicit def any2Int(in:Any):Int = {
in.toString.toDouble.toInt
}
/**
* 从文件中读取数据并解压成稀疏矩阵
*/
def unzipMatrix(filePath:String) = {
val content = getLines(filePath) (isReadable) (closeStream)
if(content == ""){
throw new Exception("文件内容为空")
}
val res = ArrayBuffer[Array[Any]]()
val gson = new Gson()
val arr = gson.fromJson(content,classOf[Array[Array[Any]]])
for(i <- 0 until arr.length){
if(i == 0){
for(j <- 0 until arr(0)(0)){
val line = ArrayBuffer[Any]()
for(k <- 0 until arr(0)(1)){
line.append(0)
}
res.append(line.toArray)
}
///初始化
} else {
res(arr(i)(0))(arr(i)(1)) = arr(i)(2)
}
}
res.toArray
}
/**
* 检测数组的容积(长和宽)
* @param inArray
* @tparam T
* @return
*/
def checkMatrix[T](inArray:Array[Array[T]]):Array[Int] = {
if(inArray.length > 0){
val i = inArray.length
val j = inArray(0).length
Array(i,j)
} else {
Array(0,0)
}
}
}
近期评论