2017年3月8日 星期三

函數 Ch7

7.1函數基本概念

1.試撰寫void kitty() 函數,當呼叫kitty() 時,螢幕上會顯示出"Hello Kitty"之字串。

ans

public class eel
{
  public static void main (String args[])
  {
   kitty();
 
  }
  public static void kitty()
  {
 System.out.print("Hello kitty");            //函數void 不用return不會錯誤。
  }

}

//印出
Hello kitty

2.試撰寫void kitty(int k) 函數,當呼叫kitty(k)時,螢幕上會顯示出k行的"Hello kitty"。

ans

import java.util.Scanner;
public class eel
{
  public static void main (String args[])
  {
      int k;
      System.out.print("輸入整數");
      Scanner scn=new Scanner(System.in);
      k=scn.nextInt();
 kitty(k);
 
  }
  public static void kitty(int k)
  {

 int i;

 for(i=0;i<=(k-1);i++)
 {
 System.out.print("\n");
 }
 System.out.print("Hello kitty");

  }

}

//題目未言明K值故以自己輸入方式答此題。

3.試撰寫int cub(int x) 函數,其作用為傳回引數X的3次方,並請計算2的3次方。

ans

public class eel
{
  public static void main (String args[])
  {
      int x=2;
      cub(x);
   
 
  }
  public static int cub(int x)
  {

 int i;

i=x*x*x;
System.out.print(i);
 return i;
}
 }

//印出
8

4.試撰寫 int addto(int n) 函數,其作用為傳回 1+2+...+n之值。請於將n設值為10,傳入 addto() 函數中。

ans

  public static void main (String args[])
  {
      int n=10;
      addto(n);
   
 
  }
  public static int addto(int n)
  {

 int i,s=0;
 for(i=0;i<=n;i++)
 {
 s=s+i;
 }

System.out.print(s);
 return s;

  }

//印出
55

5.試撰寫double fahrenheit(double c)函數,傳入攝氏溫度,計算並傳回對應的華氏溫度。請計算攝氏20度所對應的華氏溫度。其轉化公式如下:

  華氏溫度=(9/5)*攝氏溫度+32

ans

public class eel
{
  public static void main (String args[])
  {
      double c=20;
      fahrenheit(c);
   
 
  }
  public static double fahrenheit(double c)
  {

 double i;                                           <<<可能不需要再宣告double
    i=c*1.8+32;                                   <<<(9/5)無法相乘
System.out.print(i);
    return i;

  }

//印出
68

6.試撰寫一函數boolean even(int n)函數,用來判別n是否為偶數。若是,則傳回true,否則傳回false。請測試6是偶數還基數

ans

public class eel
{
  public static void main (String args[])
  {
      int n=6;
      System.out.print(even(n));
  }
  public static boolean even(int n)
  {
 
    return n%2==0?true:false; //明白 ?A:B 與函數if差異 一個是以資料型態作判別故能傳回
 
  }

}

//印出
true

7.接續練習6,試利用習題6的結果找出小於100且可以被9整除的所有偶數。

ans:

public class eel
{
  public static void main (String args[])
  {
      int n=100;
      System.out.print(even(n));
  }
  public static int even(int n)
  {
  int i;
 for(i=1;i<=n;i++)
 {

  {
  if(i%9==0)
  {
 if(i%2==0)
 {
  System.out.print(i+" ");
 }
      }
  }
 }


  return i;
 
  }

}

//印出
18 36 54 72 90 101     //不曉得為什麼會有101???

8.試撰寫double area(double r)函數,傳入半徑r,用來計算並傳回元的面積。請計算當半徑為2.0時,圓面積是多少?

ans

public class eel
{
  public static void main (String args[])
  {
      double r=2.0;
      System.out.print( area(r));
  }
  public static double area(double r)
  {
  double i;
 i=r*r*3.14159265359;
  return i;    
  }

}

//印出
12.56637061436

9.試撰寫int abs(int x)函數,其作用為傳回引數x的絕對值。請分別計算-5 2 0的絕對值

ans

public class eel
{
  public static void main (String args[])
  {
      int[] x={-5,2,0};
      for(int i=0;i<3;i++)
      {
     System.out.print(abs(x[i])+" ");
      }
     
  }
  public static int abs(int x)
  {
  int i;
 if(x<0)
 {
 i=x*-1;
 }
 else
 {
i=x;
 }
  return i;    
  }

}

//印出
5 2 0

10.試寫int min(int a,int b) 函數,傳入兩個整數,傳回較小的值。請測試min(5,8)及min(9,2)的結果。

ans:

public class eel
{
  public static void main (String args[])
  {
      int a=0,b=0;
 int c[]={5,9};
      int d[]={8,2};

      for(int i=0;i<2;i++)
      {
     if(c[0]>c[i])
     {
     c[0]=c[i];
     a=c[0];
     }
     if(d[0]>d[i])
     {
     d[0]=d[i];
     b=d[0];
     }
      }
      min(a, b);
     
  }

  public static int min(int a,int b)
  {
 int i,j;

 j=b;
 i=a;
 System.out.print("min("+i+","+j+")");
return i;

  }

}

//印出
min(0,2)      //這題有很大問題a值出不來但是b值出來了??!!。

7.2傳遞陣列到函數裡

11.試撰寫可傳回一維陣列arr的奇數個數之函數。arr的內容如下:
      int arr[ ]={8,6,9,12,47,55,10};

ans

public class eel
{
  public static void main (String args[])
  {
 int arr[ ]={8,6,9,12,47,55,10};
      int c[];
   
c=arr1(arr);                                         //可以用arr
  }    
  public static int[] arr1(int b[])                  //可設定arr與上面不相互影響
  {
 for(int i=0;i<7;i++)
 {
if(b[i]%2==1)
{
System.out.print(b[i]+" ");
}
 }
 return b;

  }

}

//印出
9 47 55

12.試撰寫可傳回一維陣列a最小值函數,陣列a={75,29,38,45,16}。

13.試撰寫可傳回一維陣列a最小值之索引值的函數,陣列a={75,29,38,45,16}

ans//不需要用兩個函數請參閱15題

public class eel
{
public static void main(String[] args) {
int a[]={75,29,1,45,16,37,2,9,10};
System.out.println("陣列a的最小值="+ minarray(a));
System.out.println("最小值索引值a["+ minindex(a)+"]");
}


public static int minarray(int data[]){
int min=data[0];
for(int i=0;i<data.length;i++){
   if(min>data[i]){  //找出陣列中的最小值
   min=data[i];
   }
}
   return min; //回傳最小值
}

 
public static int minindex(int data[]){
int minindex=0;  //必須另外設個整數變數判斷最小值的索引值
int min=data[0];
for(int i=0;i<data.length;i++){
   if(min>data[i]){  //找出陣列中的最小值
   min=data[i];
   minindex=i;
   }
/*
條件是min>data[i],如果只在if條件下將minindex=i,會造成i=迴圈執行次數
因此先將min=data[i],讓值互換,再寫上minindex=i,這樣子索引值才會正確
*/  
}
return minindex; //回傳最小值的索引值
}
}

//印出
陣列a的最小值=1
最小值索引值a[2]

14.設計一函數,可傳回一個二維陣列a的最大值a={{75,29,10},{38,45,16}}。

ans

public class eel
{
public static void main(String[] args) 
{
int a[][]={{75,29,10},{38,45,16}};
System.out.print("max="+max(a));
}
public static int max(int bata[][])
{
int max1=bata[0][0];
for(int i=0;i<bata.length;i++)
{
for(int j=0;j<bata[i].length;j++)
{
if(max1<bata[i][j])
{
max1=bata[i][j];
}
}
}
return max1;
}
}

//印出
max=75

15.試寫一函數,可傳回一維振烈a中最大值與最小值的成積,a={75,29,10,38,45,16}。

ans//將印出放在 函數裡面 就可以印出兩個以上的變數max1 min1

public class eel
{
public static void main(String[] args) 
{
int a[]={75,29,10,38,45,16};
two(a);
}
public static int two(int bata[])
{
int min1=bata[1];
int max1=bata[0];
for(int i=0;i<bata.length;i++)
{
if(max1<bata[i])
{
max1=bata[i];
}
if(min1>bata[i])
{
min1=bata[i];
}
}
System.out.print("max="+max1+"\n");
System.out.print("min="+min1);
return max1;
}
}

//印出
max=75
min=10

16.試撰寫一函數,可用來接收二維陣列,傳回值為此二維陣列a所有元素平均值。
陣列a的內容如下:
int a[][]={{2,4,6},{1,3,5},{8,9}}

ans//void main與 method函數是可以不同資料型態

public class eel
{
public static void main(String[] args)
{
int a[][]={{2,4,6},{1,3,5},{8,9}};
   avarage(a);
}
public static double avarage(int bata[][])
{
double avr=0,sum=0;

for(int i=0;i<bata.length;i++)
{
for(int j=0;j<bata[i].length;j++)
{
avr=avr+bata[i][j];
sum=sum+1;
}
}
System.out.print("avr="+avr/sum);
return avr;
}
}
//印出
avr=4.75

17.試撰寫一函數,可用來接收二維陣列,計算二維陣列每個元素的平方。
陣列a的內容如下:
int a[][]={{1,4,8},{2,9,5},{8,9}};

ans:
public class eel
{
public static void main(String[] args)
{
int a[][]={{1,4,8},{2,9,5},{8,9}};
   square(a);
}
public static int square(int bata[][])
{
int sq=0;

for(int i=0;i<bata.length;i++)
{
for(int j=0;j<bata[i].length;j++)
{
sq=bata[i][j]*bata[i][j];
System.out.print(sq+" ");
}
System.out.print("\n");
}
return sq;
}
}

//印出
1 16 64 
4 81 25 
64 81 

18.試寫-double avg(int arr[])函數,傳回整數陣列的平均值,並於avg()中呼叫 void show(int arr[])函數,印出陣列的內容。arr{75,29,10,38,45,17}

ans
public class eel
{
public static void main(String[] args)
{
int a[]={75,29,10,38,45,17};
   avg(a);
}
public static double avg(int avg[])
{
double j = 0,sum=0;

for(int i=0;i<avg.length;i++)
{
j=j+avg[i];
sum=sum+1;
System.out.print(avg[i]+" ");
}
System.out.print("\n"+"avg="+j/sum);
return j;
}
}
//印出
75 29 10 38 45 17
avg=35.666666666666664

19.費氏數列(Fibonacci sequence)的定義為






其中n為整數,也就是說,費氏數列任一項的值等於前兩項的和,且fib(1)=fib(2)=1。
(a) 試撰寫-long fib(int n) 函數,利用for迴圈計算第50個費氏數列的值。
(b) 試撰寫-long fib(int n) 函數,利用遞迴的概念計算第50個費氏數列的值。
(c) 試比較以迴圈和遞迴的方式來計算費氏數列時,在執行的時間上會有甚麼樣的差異?哪一種方式執行效率最好?

ans

(a)試撰寫-long fib(int n) 函數,利用for迴圈計算第50個費氏數列的值。
public class eel
{

public static void main(String[] args)
{
        int x=50;
fib(x);

}
     public static double fib(int n)
     {
    double b=0;
    int a[]=new int[n];
    a[0]=a[1]=1;
    for(int i=2;i<n;i++)
    {
    a[i]=a[i-1]+a[i-2];
    System.out.print((i+1)+"="+a[i]+"\n");
    }
   
return n;
     }

}

//印出
3=2
.
.
.
.
50=-298632863

(b) 試撰寫-long fib(int n) 函數,利用遞迴的概念計算第50個費氏數列的值。
public class eel
{

public static void main(String[] args)
{
        int x=50;
System.out.print("fib(50)="+fib(x));

}
     public static double fib(int n)
     {
    int b=0;
    if(n<=2)
    {
    return 1;
    }
    else
    {
    b=(int) (fib(n-1)+fib(n-2));
    return b;
    }
   
     }

}
//印出
fib(50)=2.147483647E9

(c) 試比較以迴圈和遞迴的方式來計算費氏數列時,在執行的時間上會有甚麼樣的差異?哪一種方式執行效率最好?

ans:
所謂遞迴(recursive)就是函數本身呼叫自己。迴圈(loop)則是while for,根據書上,使用遞迴函數可以讓程式碼變得簡潔,可提升效率但需要有停止條件。例如fib(50)。否則堆疊(stack)空間不足而當掉。但是根據ab兩個題目b的go時間偏長效率是否比較好,新手的我不感妄下定論。


20.試撰寫遞迴函數 double rpower(double b,int n),用來計算b的n次方,並利用此函數來計算5.0^4。

ans

public class eel
{

public static void main(String[] args)
{
        int a=5;
System.out.print("rpower(5,4)="+rpower(a, 4));


}
     public static double rpower(double b,int n)
     {
     
    if(n==0)
       {
        return 1;
       }
       else
       {
        return b*rpower(b,n-1);     //兩個不同資料型態double為開根號底數int為次方且n-1的部分
       }                                          //更動則錯誤(n+1或n)似乎比較像固定的數學公式(高中數學..)
    }
}
//印出
rpower(5,4)=625.0

21.試以遞迴的方式撰寫函數 int sum(int n),利用遞迴公式
sum(n)=n+sum(n-1),sum(1)=1
用來計算1+2+3+....+n的值,n值請設值為10。

ans

public class eel
{

public static void main(String[] args)
{
        int a=10;
System.out.print("sum(n)="+sum(a));


}
     public static int sum(int n)
     {
     
    if(n==1)
       {
        return 1;
       }
       else
       {
        return n+sum(n-1);
       }
   
     }

}
//印出
sum(n)=55。

22.試以遞迴的方式計算X^n的值,並計算3^8與7^4之值

ans
參考20題
public class eel
{

  public static void main(String[] args)
  {
        int a=5;
   System.out.print("rpower(3,8)="+rpower(3, 8)+"\n");
   System.out.print("rpower(7,4)="+rpower(7, 4));

  }
     public static double rpower(double b,int n)
     {
     
      if(n==0)
         {
          return 1;
         }
         else
         {
          return b*rpower(b,n-1);  
         }              

     }
}

//印出
rpower(3,8)=6561.0
rpower(7,4)=2401.0

23.試撰寫遞迴函數int rsum(int n)來求算1X2+2X3+3X4+...+(n-1)Xn之和,n值請設值為5。

ans
public class eel
{

  public static void main(String[] args)
  {    
   System.out.print("rsum(5)="+rsum(5));
  }
     public static int rsum(int n)
     {
    if(n==2)
    return(2*1);
    else
    return n*(n-1) + rsum(n-1);//+rsum(n-1)直接呼叫少1的自己函數---沒想到
                                                           //rsum(1)是不存在的,意思是指有rsum(2)+(3)+(4)+(5)
     }
}

24.試撰寫一組可以計算三角形面積的多載化函數,格式為 triangle(base, height),base 與hight可同為 int 或 float, 傳回值得型態為float。
( 三角形面積 =(base*height)/2 )
請計算三角形的底為6,高為3及底為4.2,高為3.3時,面積各是多少?

ans

public class eel
{

  public static void main(String[] args)
  {    
   System.out.print("triangle1="+triangle(6,3)+"\n");
   System.out.print("triangle2="+triangle(4.2f,3.3f));

  }
     public static float triangle(float d,float e)
     {
   
    return d*e/2;
     }
     public static float triangle(int base,float height)
     {
   
    return base*height/2;  
     }
     public static float triangle(int base,int height)
     {
   
    return base*height/2;
     }
     public static float triangle(float base,int height)
     {
   
    return base*height/2;
     }
}

//印出
triangle1=9.0
triangle2=6.9299994

25. 試撰寫max()函數的多載,其中max引數的型態為int,且可以有兩個三個引數,函數的傳回值為這些引數的最大值,傳回值的型態也是int。請在主程式呼叫max(8,2)及max(1,5,9),印出傳回值。

ans:
public class eel
{

  public static void main(String[] args)
  {    
System.out.println("max(8,2)="+max(8,2));
System.out.print("max(1,5,9)="+max(1,5,9));
  }
     public static int max(int a,int b)
     {
    if(a>b)
    return a;
    else
    return b;
   
     }
     public static int max(int c,int d,int e)
     {
    int x[]={c,d,e};
    int xx=0;
   
    for(int i=0;i<3;i++)
    if(x[i]>x[0])
    x[0]=x[i];
    xx=x[0];
    return xx;
     
     }

}
\\印出
max(8,2)=8
max(1,5,9)=9

26.試撰寫一組可以傳回絕對值得多載化函數,格式為abs(n),引數型態可為int float或double,傳回值的型態與所接收的引數型態相同。請列印出abs(-6) abs(-3.5f)與abs(-2.12345)的結果。

ans
public class eel
{

  public static void main(String[] args)
  {    
 System.out.println("|-6|="+abs(-6));
 System.out.println("|-3.5f|="+abs(-3.5f));
 System.out.print("|-2.12345|="+abs(-2.12345));
  }
     public static int abs(int a)
     {
    if(a<0)
    return a*-1;
return a;

     }
     public static float abs(float a)
     {
    if(a<0)
    return a*-1;
return a;

     }
     public static double abs(double a)
     {
    if(a<0)
    return a*-1;
return a;

     }  
}

//印出
|-6|=6
|-3.5f|=3.5
|-2.12345|=2.12345

27.試於程式中建立計算圓面積之多載化函數,其名成為circle(r),引數r為半徑值,其中半徑的型態可為int float或double,圓周率請用3.14,傳回值的型態為均為double。
(圓面積=3.14*r*r)
請計算半徑為2 2.3f與2.3時,圓面積各是多少?

ans

public class eel
{

  public static void main(String[] args)
  {    
 System.out.println("r=2 面積="+circle(2));
 System.out.println("r=2.3f 面積="+circle(2.3f));
 System.out.print("r=2.3 面積="+circle(2.3));
  }
     public static int circle(int a)                    //多載函數引數變數可相同,都是a。
     {
    return (int) (3.14*a*a);
     }
     public static float circle(float a)
     {
    return (float) (3.14*a*a);
     }
     public static double circle(double a)
     {
    return (double) (3.14*a*a);
     }
}

//印出
r=2 面積=12
r=2.3f 面積=16.6106
r=2.3 面積=16.610599999999998