我在第一个练习的Scala中的函数式编程原理中的scala代码有什么问题

时间:2017-08-05 14:46:37

标签: scala

我是scala初学者。我正在学习Functional Programming in Scala。但是当我做第一次练习时,我会遇到这个问题。第一个练习是:

    1
   1 1
  1 2 1
 1 3 3 1
1 4 6 4 1
     

三角形边缘的数字都是1,每个数字都是1   三角形内部是它上面两个数字的总和。写一个   通过a计算Pascal三角形元素的函数   递归过程。

     

通过在Main.scala中实现pascal函数来完成此练习,   它取一列c和一行r,从0开始计数并返回   三角形中那个位置的数字。例如,pascal(0,2)= 1,   pascal(1,2)= 2和pascal(1,3)= 3.

这是我的第一个代码:

package recfun

object Main {
  def main(args: Array[String]) {
    println("Pascal's Triangle")
    for (row <- 0 to 10) {
      for (col <- 0 to row)
        print(pascal(col, row) + " ")
      println()
    }
  }

  var i = 0

  /**
    * Exercise 1
    */
  def pascal(c: Int, r: Int): Int = {
    if(c==r||c==0)
      1
    else
      i = pascal(c - 1, r - 1) + pascal(c, r - 1)
    i
  }

  /**
   * Exercise 2
   */
    def balance(chars: List[Char]): Boolean = ???

  /**
   * Exercise 3
   */
    def countChange(money: Int, coins: List[Int]): Int = ???
  }

但我得到了这个结果

0 
0 0 
0 0 0 
0 0 0 0 
0 0 0 0 0 
0 0 0 0 0 0 
0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 0 

然后我尝试更改我的代码,并得到正确的结果。

package recfun

object Main {
  def main(args: Array[String]) {
    println("Pascal's Triangle")
    for (row <- 0 to 10) {
      for (col <- 0 to row)
        print(pascal(col, row) + " ")
      println()
    }
  }


  /**
    * Exercise 1
    */
  def pascal(c: Int, r: Int): Int = {
    if(c==r||c==0)
      1
    else
       pascal(c - 1, r - 1) + pascal(c, r - 1)
  }

  /**
   * Exercise 2
   */
    def balance(chars: List[Char]): Boolean = ???

  /**
   * Exercise 3
   */
    def countChange(money: Int, coins: List[Int]): Int = ???
  }

我想知道为什么我的第一个代码是worng?

2 个答案:

答案 0 :(得分:1)

在第二个代码中,if语句的值是函数的结果。在第一个函数中,i是函数的结果,并且不使用if语句的值。所有重要的是if语句对i的作用。 if语句的then部分不对i做任何事情,所以如果采用then部分,结果将是i的前一个值,它将为0

答案 1 :(得分:1)

There is problem in your first pascal function
i=0
def pascal(c: Int, r: Int): Int = {
    if(c==r||c==0)
      1
    else
      i = pascal(c - 1, r - 1) + pascal(c, r - 1)
    i
  }

In if-else block always var 'i' is returned which has value as 0. In else condition it is assigned but as recurring pascal will return initial 'i' value (0), it will be always 0.

It is not bad practise to use global variable in function only for returning any value so second approach is more correct still if you want to return value with global variable at least assign value in if and else block as below

i=0
def pascal(c: Int, r: Int): Int = {
    if(c==r||c==0)
      i=1    // this will be assigned for the first time and when r==c
    else
      i = pascal(c - 1, r - 1) + pascal(c, r - 1) // this will be assigned for subsequent calculations
    i  // it will return value which is calculated in if else block
  }

**It is recommended to use proper curly braces {} to avoid such confusion.** 

def pascal(c: Int, r: Int): Int = {
    if(c==r||c==0){      
        i=1
    } else{    
       i = pascal(c - 1, r - 1) + pascal(c, r - 1)
   } 
    i
  }

In the second code, you just have if-else block and no statement after this block and scala is smart and return from if and else block only.

希望它能回答你的问题。