-1

I wrote sum code in scala to find the majority element(the element which appears more than n/2 times where 'n' is the no.of elements in an array.I want to know where there is functional / scala native style of version(which includes match cases and transformations like "map/"flatmap" etc..) for the below imperative style of scala code which includes looping. The code which i used in:

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);
  }
}

please let me know, whether it is possible to write/ convert imperative style to functional version in scala(which uses match cases) for any scenario.

Mahesh
  • 178
  • 3
  • 14
  • Not sure what the point of the question is. Recursion can be used in imperative code, but why would you want to? Scala can be written in imperative style, but why would you want to? (Also, this code would be much more readable/understandable if you included some indenting.) – jwvh Feb 11 '16 at 07:26
  • Hi @jwvh ! Here my point is, i want to know how can i write the recursive version of the above code. And is it possible to add "map"/"flatmap" on array elements to get the same functionality as shown in the above code. Because i want to learn/write my code in scala's native style which make much more use of scala's collection libray and semantics than imperative style which includes loopings as shown in above code. Any example code for converting above code to scala's native style is much more appreciated. – Mahesh Feb 11 '16 at 07:51
  • Ah, then the title of your question is a bit misleading. You don't want to just add recursion, you'd like to convert this imperative code to functional code, which might not involve recursion at all. – jwvh Feb 11 '16 at 08:02

3 Answers3

2

If you're only interested in the final result (and so you don't need isMajority etc), it's very simple

  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)

Group equal elements into lists (the values of the Map returned by GroupBy). Pick the longest list. If its length is more than half the list, then it's a majority, return Some(the head) (any element will do, they're all the same value). Otherwise, return None

The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
1

The transition from imperative thinking to functional thinking takes time and study. One approach is to find code examples here on SO and, with the help of the Standard Library, break it down until you understand what's going on.

Here's a little something to get you started.

def isMajority(arr:Array[Int],cand:Int):Boolean =
  arr.count(_ == cand) > arr.size/2
jwvh
  • 50,871
  • 7
  • 38
  • 64
0

Threr is no Native Scala Style, but code can be Functional Style(value oriented)

(No var, No Side-Effect, Pure Function)

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")
}
blueiur
  • 1,447
  • 1
  • 11
  • 17