是否可以在 Scala 中为以下命令式代码编写功能版本
is it possible to write functional version for below imperative code in scala
我在 scala 中编写求和代码来查找多数元素(出现次数超过 n/2 的元素,其中 'n' 是 array.I 中的 no.of 元素想知道以下命令式样式的 Scala 代码(包括循环)的功能/Scala 本机版本版本(包括匹配案例和转换,如 "map/"flatmap" 等..)在哪里。我在中使用的代码:
object MajorityElement{
def printMajority(arr:Array[Int]) ={
var cand:Int=findCandidate(arr);
if(isMajority(arr,cand))
println(cand);
else
println("No Majority Element");
}
def isMajority(arr:Array[Int],Cand:Int):Boolean ={
var count=0;
for(i <- 0 until arr.length){
if(arr(i)== Cand)
count+=1;
}
if (count > arr.size/2)
return true;
else false
}
def findCandidate(arr:Array[Int]):Int ={
val s = arr.size
var majIndex:Int = 0;
var count = 1;
for(i <- 0 until arr.length){
if(arr(majIndex) == arr(i))
count+=1;
else
count-=1;
if(count==0)
{
majIndex = i;
count =1
}
}
return arr(majIndex);
}
}
请告诉我,是否可以在任何情况下在 scala(使用匹配案例)中编写/转换命令式样式到函数式版本。
从命令式思维到功能性思维的转变需要时间和学习。一种方法是在 SO 上找到代码示例,并在 Standard Library 的帮助下分解它,直到您了解发生了什么。
这里有一些可以帮助您入门的小东西。
def isMajority(arr:Array[Int],cand:Int):Boolean =
arr.count(_ == cand) > arr.size/2
Threr 不是 Native Scala 风格,但代码可以是函数式风格(面向值)
(无变量,无副作用,纯函数)
object MajorityElement {
case class Candidate(idx: Int, count: Int)
def solve(arr: Array[Int]): Option[Int] = {
val candidate = findCandidate(arr)
if (isMajority(arr, candidate)) Option(arr(candidate.idx))
else None
}
def isMajority(arr: Array[Int], candidate: Candidate) =
arr.count(_ == arr(candidate.idx)) > arr.size / 2
def findCandidate(arr: Array[Int]): Candidate =
arr.indices.foldLeft(Candidate(0, 1)) { (acc, idx) =>
val newAcc =
if (arr(acc.idx) == arr(idx)) acc.copy(count = acc.count + 1)
else acc.copy(count = acc.count - 1)
if (newAcc.count == 0) Candidate(idx, 1)
else newAcc
}
}
val arr = Array(1, 1, 1, 2, 3, 4, 1)
val ret = MajorityElement.solve(arr)
ret match {
case Some(n) => println(s"Found Majority Element: $n")
case None => println("No Majority Element")
}
如果您只对最终结果感兴趣(因此您不需要 isMajority
等),这很简单
def findMajority(xs: List[Int]) = {
val mostFrequent = xs.groupBy(identity).values.maxBy(_.length)
if (mostFrequent.length >= xs.length / 2) Some(mostFrequent.head) else None
}
findMajority(List(1, 2, 2, 2, 3, 3, 3, 3, 3, 4))
//Option[Int] = Some(3)
将相等的元素分组到列表中(Map
return 的值由 GroupBy
编辑)。选择最长的列表。如果它的长度超过列表的一半,那么它就是多数,return Some(
head)
(任何元素都可以,它们都是相同的值)。否则,returnNone
我在 scala 中编写求和代码来查找多数元素(出现次数超过 n/2 的元素,其中 'n' 是 array.I 中的 no.of 元素想知道以下命令式样式的 Scala 代码(包括循环)的功能/Scala 本机版本版本(包括匹配案例和转换,如 "map/"flatmap" 等..)在哪里。我在中使用的代码:
object MajorityElement{
def printMajority(arr:Array[Int]) ={
var cand:Int=findCandidate(arr);
if(isMajority(arr,cand))
println(cand);
else
println("No Majority Element");
}
def isMajority(arr:Array[Int],Cand:Int):Boolean ={
var count=0;
for(i <- 0 until arr.length){
if(arr(i)== Cand)
count+=1;
}
if (count > arr.size/2)
return true;
else false
}
def findCandidate(arr:Array[Int]):Int ={
val s = arr.size
var majIndex:Int = 0;
var count = 1;
for(i <- 0 until arr.length){
if(arr(majIndex) == arr(i))
count+=1;
else
count-=1;
if(count==0)
{
majIndex = i;
count =1
}
}
return arr(majIndex);
}
}
请告诉我,是否可以在任何情况下在 scala(使用匹配案例)中编写/转换命令式样式到函数式版本。
从命令式思维到功能性思维的转变需要时间和学习。一种方法是在 SO 上找到代码示例,并在 Standard Library 的帮助下分解它,直到您了解发生了什么。
这里有一些可以帮助您入门的小东西。
def isMajority(arr:Array[Int],cand:Int):Boolean =
arr.count(_ == cand) > arr.size/2
Threr 不是 Native Scala 风格,但代码可以是函数式风格(面向值)
(无变量,无副作用,纯函数)
object MajorityElement {
case class Candidate(idx: Int, count: Int)
def solve(arr: Array[Int]): Option[Int] = {
val candidate = findCandidate(arr)
if (isMajority(arr, candidate)) Option(arr(candidate.idx))
else None
}
def isMajority(arr: Array[Int], candidate: Candidate) =
arr.count(_ == arr(candidate.idx)) > arr.size / 2
def findCandidate(arr: Array[Int]): Candidate =
arr.indices.foldLeft(Candidate(0, 1)) { (acc, idx) =>
val newAcc =
if (arr(acc.idx) == arr(idx)) acc.copy(count = acc.count + 1)
else acc.copy(count = acc.count - 1)
if (newAcc.count == 0) Candidate(idx, 1)
else newAcc
}
}
val arr = Array(1, 1, 1, 2, 3, 4, 1)
val ret = MajorityElement.solve(arr)
ret match {
case Some(n) => println(s"Found Majority Element: $n")
case None => println("No Majority Element")
}
如果您只对最终结果感兴趣(因此您不需要 isMajority
等),这很简单
def findMajority(xs: List[Int]) = {
val mostFrequent = xs.groupBy(identity).values.maxBy(_.length)
if (mostFrequent.length >= xs.length / 2) Some(mostFrequent.head) else None
}
findMajority(List(1, 2, 2, 2, 3, 3, 3, 3, 3, 4))
//Option[Int] = Some(3)
将相等的元素分组到列表中(Map
return 的值由 GroupBy
编辑)。选择最长的列表。如果它的长度超过列表的一半,那么它就是多数,return Some(
head)
(任何元素都可以,它们都是相同的值)。否则,returnNone