c# 课堂总结7--函数
函数:
数据类型-变量类型-运算符号表达式-语句(顺序,分支,循环)-数字
程序里的函数:能完成一个相对独立功能的代码块。
数学里的函数:高度抽象。
函数四要素:函数名,输入(参数),输出(返回值类型),加工(函数体)
函数定义:
[static]返回类型 函数名(输入参数列表)
{
//函数体-加工
}
函数调用:
[数据类型 变量名]=函数(参数);
函数名(参数);---用于无返回类型的函数
数据类型 变量=函数名(参数);---用于有返回类型的函数
1.参数匹配
在调用函数时,调用的参数和函数定义的参数保持一对待:个数,类型,对应。
形参:形式参数。--函数定义的参数。
实参:实际参数。--函数调用的参数。
实参、形参传值的规律--传址,传值。
传值:鉴于整型、浮点、bool、char这几种内建函数传递参数的时候,默认都是传值。
传值是把实参做一个副本(copy)传递给形参。
m=30;
Add(m);
static void Add(int a)
{
a+=20;
}
传址:默认情况下,数组就是传地址。字符串也是传地址。
对于内建的整型、浮点、bool、char这些类型,如果要变成传址的话,需要在前面加ref
m=30;
Add(ref m);
static void Add(ref int a)
{
a+=20;
}
对于传值和传址大家要记住:
1.什么是传值,什么传址?这个要分清楚。
2.默认情况下,哪些类型传值?哪些类型传址?
3.对于默认传值的类型,如何让他们变为传址?ref
以后为了防止因为传值、传址引起的错误,建议采用返回值的形式,明确返回的数据。
例题部分
eg. 传值的方法
static void Main(string[] args)
{
int m = ;
Console.WriteLine("Main函数第一次打印:"+m);//
Add(m);
Console.WriteLine("Main函数第二次打印:" + m);//
}
static void Add(int a)
{
Console.WriteLine("Add函数第一次打印:"+a);//
a += ;
Console.WriteLine("Add函数第二次打印:"+a);//
} eg. 传址方式,加ref
static void Mainb(string[] args)
{
int m = ;
Console.WriteLine("Main函数第一次打印:" + m);//
Add1( m);
Console.WriteLine("Main函数第二次打印:" + m);//
Console.WriteLine("Main函数第三次打印:" + m);//
Add2(ref m);
Console.WriteLine("Main函数第四次打印:" + m);//
} static void Add1(int a)
{
Console.WriteLine("Add1传值函数第一次打印:" + a);//
a += ;
Console.WriteLine("Add1传值函数第二次打印:" + a);//
} static void Add2(ref int a)
{
Console.WriteLine("Add2传址函数第一次打印:" + a);//
a += ;
Console.WriteLine("Add2传址函数第二次打印:" + a);//
} eg. 传址与传值 数组名 传址,数组元素传值。
static void Main1(string[] args)
{
int[] m = new int[] {,,, }; //打印原值
foreach (int a in m)
{
Console.Write(a+"\t");
} //调用函数,传递整个数组
Add(m);//传得是数组名,传的是地址。 Add9(m[]);//传得是数组的某个元素,是传值。
//打印改变后的值
foreach (int a in m)
{
Console.Write(a+"\t");
}
} static void Add9(int a)
{
Console.WriteLine("Add9被调用了,在Add9中把传进来的" + a + "变成了" + a * );
a = a * ;
} static void Add(int[] b)
{
for (int i = ; i < b.Length; i++)
{
b[i] *= ;
}
}
2、函数重载?
在函数重载时,应包括函数签名的所有方面,例如,有两个不同的函数,他们分别值参数和引用参数。
static void ShowDouble(ref int val)
{
....
}
static void ShowDouble(int val)
{
....
}
选择使用哪个版本纯粹是根据是否包含ref关键字来确定的,下面的代码将调用引用版本:
ShowDouble(ref val);
下面的代码将调用值版本:
ShowDouble(val);
另外还要根据参数的个数来区分函数。
3、委托。
eg.1 对战改 函数
//人人对战 class class1
{
static void Mainmydemo5(string[] args)
{
string[] jn=new string[];//return 与out 的区别 :out 返回值时,不用规定数组的大小,return返回值是,数组必须创建出多大的。eg买东西!
//int[] sh=new int[10];
int[] sh;
jn = JiNeng(jn, out sh);//数组默认就是传址,不需要加ref,但有的时候不同 //string[] jn;
//int[] sh;
//JiNeng(out jn, out sh); player p1=new player();
player p2=new player();
ShuRu(ref p1.name, ref p2.name); //攻击方数据输出
p1 = PlayerPeiZhi(jn, sh, p1);
PlayerPeiZhiShuChu(p1); //防守方数据输出
p2 = PlayerPeiZhi(jn, sh, p2);
PlayerPeiZhiShuChu(p2); //战斗开始
Console.WriteLine("→→→→→→→→→"); Console.WriteLine("请按空格键开始对战");
ConsoleKeyInfo key = Console.ReadKey();
Console.Clear(); if (key.Key.ToString().ToLower() == "spacebar")
{
while (true)
{
#region 战斗开始
//攻击方攻击
ZhanDou(ref p1, ref p2); Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood); //退出循环的判断!
bool m = TuiChu(ref p1, ref p2);
if (m)
{
break;
}
else
{ } //防守方攻击
ZhanDou(ref p2, ref p1); Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood); //退出循环的判断!
bool n = TuiChu(ref p1, ref p2);
if (n)
{
break;
}
else
{ }
#endregion Thread.Sleep();
}
}
} /// <summary>
/// 输出玩家的配置
/// </summary>
/// <param name="t">形参 玩家</param>
private static void PlayerPeiZhiShuChu(player t)
{
player a = new player();
a = t;
Console.WriteLine("攻击方的战斗力如下:");
Console.WriteLine("姓名:" + a.name + ",血量:" + a.blood + ",攻击力:" + a.attack + ",防御力:" + a.defence + ",闪避力:" + a.shanbi);
Console.WriteLine("技能1为:{0},技能2为:{1},技能3为{2} 。", a.jineng[], a.jineng[], a.jineng[]);
} /// <summary>
/// 判断退出条件
/// </summary>
/// <param name="a">玩家1的信息</param>
/// <param name="b">玩家2的信息</param>
/// <returns>为 真 则退出,为 假 则继续。</returns>
private static bool TuiChu(ref player a, ref player b)
{
bool c;
if (b.blood == )
{
Console.WriteLine(a.name + "将" + b.name + "KO!");
c = true;
//break;
}
else if (a.blood == )
{
Console.WriteLine(b.name + "将" + a.name + "KO!");
c = true;
//break;
}
else if (a.blood == && b.blood == )
{
Console.WriteLine("平局!");
c = true;
//break;
}
else
{
c = false;
}
return c;
} /// <summary>
/// 战斗开始
/// </summary>
/// <param name="p1">玩家1的信息</param>
/// <param name="p2">玩家2的信息</param>
private static void ZhanDou(ref player a, ref player b)
{
//普通攻击
Random m1 = new Random();
//int a1 = m1.Next(3);
if (b.shanbi >= m1.Next())
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(a.name + "对" + b.name + "使用普通攻击,但被" + b.name + "躲过了。");
Console.ForegroundColor = ConsoleColor.Red;
//Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood); Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
//Thread.Sleep(1000);
}
else
{
b.blood = b.blood - a.attack + b.defence;
Console.ForegroundColor = ConsoleColor.Black;
Console.WriteLine(a.name + "使用普通攻击,对" + b.name + "造成了" + (a.attack - b.defence) + "点伤害。");
Console.ForegroundColor = ConsoleColor.Red;
if (b.blood <= )//判断是否为负血量,如果为<0,则让他=0,自己做的时候没想到
{
b.blood = ;
}
//Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
//Thread.Sleep(1000);
} //技能攻击
Random m2 = new Random();
int a1 = m2.Next();
if (m2.Next() >= m2.Next())
{
Console.ForegroundColor = ConsoleColor.Blue;
Console.WriteLine(a.name + "释放了" +a.jineng[a1] + ",对" + b.name + "造成了" + a.shanghai[a1] + "伤害。");
b.blood = b.blood - Convert.ToInt32(a.shanghai[a1]);
Console.ForegroundColor = ConsoleColor.Red;
if (b.blood <= )//判断是否为负血量,如果为<0,则让他=0,自己做的时候没想到
{
b.blood = ;
}
//Console.WriteLine(p1.name + "的血量为:" + p1.blood + "," + p2.name + "的血量为:" + p2.blood);
//Thread.Sleep(1000);
}
}//用ref 的目的就是传的a,b的地址这样才能够输出a,b因为战斗而改变的数据 /// <summary>
/// 战斗力配置
/// </summary>
/// <param name="jn">选择3个技能</param>
/// <param name="sh">对应出3个技能的伤害</param>
/// <param name="p1">对应的玩家</param>
/// <returns>返回玩家配置</returns>
private static player PlayerPeiZhi(string[] jn, int[] sh, player p)
{
int seed1 = ;
if (p.name.Length == )
{
seed1 = (int)(Convert.ToChar(p.name.Substring(, ))) + (int)(Convert.ToChar(p.name.Substring(, )));
}
else if (p.name.Length == )
{
seed1 = (int)(Convert.ToChar(p.name.Substring(, ))) + (int)(Convert.ToChar(p.name.Substring(, ))) +
(int)(Convert.ToChar(p.name.Substring(, )));
}
Random r1 = new Random(seed1); p.blood = r1.Next() + ;//血量
p.attack = r1.Next() + ;//攻击力
p.defence = r1.Next() + ;//防御力
p.shanbi = r1.Next() + ;//闪避
p.jineng = new ArrayList();//具体到当前p1.jineng这样集合。把结构体里的jineng类面对p1创建出p1.jineng的对象。
p.shanghai = new ArrayList(); //技能+伤害
for (int i = ; i < ; i++)
{
Random q = new Random();
int a = q.Next();
if (!p.jineng.Contains(jn[a]))
{
p.jineng.Add(jn[a]);
p.shanghai.Add(sh[a]);
}
else
{
i--;
}
} return p;
} /// <summary>
/// 技能及伤害
/// </summary>
/// <param name="jn">技能</param>
/// <param name="sh">伤害</param>
private static string[] JiNeng(string[] jn,out int[] sh)//或者static void JiNeng(out string[] jn, out int[] sh)
{ jn = new string[] { "横扫千军", "釜底抽薪", "降龙十巴掌", "雷霆一击", "死亡一指", "紧箍咒", "五雷轰顶", "装嫩", "卖萌", "青年2B打法" };
sh = new int[] { , , , , , , , , , };
return jn;
} /// <summary>
/// 输入姓名
/// </summary>
/// <param name="a">玩家1</param>
/// <param name="b">玩家2</param>
private static void ShuRu(ref string a, ref string b)//此处错误,因为a,b传的是值
{
Console.WriteLine("请输入出战方的姓名:");
a = Console.ReadLine();
Console.WriteLine("请输入防守方的姓名:");
b = Console.ReadLine();
} //private static void ShuRu(string a, string b)//此处错误,因为a,b传的是值
//{
// Console.WriteLine("请输入出战方的姓名:");
// a = Console.ReadLine();
// Console.WriteLine("请输入防守方的姓名:");
// b = Console.ReadLine();
//} }
eg.2 推箱子
#region eg 1 推箱子 static void Main1(string[] args)
{
int a = ;
while (true)
{
int[,] map = new int[, ];
map = Map(a); MapDisplay(map); int x = ZuoBiao(map, , );
int y = ZuoBiao(map, , );
int r = ZuoBiao(map, , );
int s = ZuoBiao(map, , );
while (map[r, s] != )
{
ConsoleKeyInfo key = Console.ReadKey(); #region 向右走
if (key.Key.ToString() == "RightArrow")
{
if (y < )//右移最大不会超过y=8坐标
{
if (map[x, y + ] == )//人的下一步只能是空地,或箱子,或墙,或终点,先判断空地
{
map[x, y + ] = ;
map[x, y] = ;
//走过终点后,再让终点恢复出来!
//if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3;
y++; }
else if (map[x, y + ] == )//人的下一步是终点
{
map[x, y + ] = ;
map[x, y] = ;
y++;
}
else if (map[x, y + ] == && map[x, y + ] == )//人的下一步是箱子
{
map[x, y + ] = ;
map[x, y + ] = ;
map[x, y] = ; //if (a[8, 8] != 2 && a[8, 8] != 1)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2 && a[8, 6] != 1)
// a[8, 6] = 3; y++;
}
else if (map[x, y + ] == && map[x, y + ] == )//人的下一步是箱子,箱子的下一步是终点
{
map[x, y + ] = ;
map[x, y + ] = ;
map[x, y] = ; //if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3; y++;
}
else //其中包括,人的下一步是墙,箱子的下一步是墙
Console.WriteLine("\a");
}
else
Console.WriteLine("\a");
}
#endregion #region 向左走
if (key.Key.ToString() == "LeftArrow")
{
if (y > )//左移最小不会小于y=1坐标
{
if (map[x, y - ] == )//人的下一步只能是空地,或箱子,或墙,先判断空地
{
map[x, y - ] = ;
map[x, y] = ; //if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3;
y--;
}
else if (map[x, y - ] == )
{
map[x, y - ] = ;
map[x, y] = ;
y--;
}
else if (map[x, y - ] == && map[x, y - ] == )//人的下一步是箱子
{
map[x, y - ] = ;
map[x, y - ] = ;
map[x, y] = ; if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ; y--;
}
else if (map[x, y - ] == && map[x, y - ] == )//人的下一步是箱子,箱子的下一步是终点
{
map[x, y - ] = ;
map[x, y - ] = ;
map[x, y] = ; if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ; y--; }
else //其中包括,人的下一步是墙,箱子的下一步是墙
Console.WriteLine("\a");
}
else
Console.WriteLine("\a");
}
#endregion #region 向上走
if (key.Key.ToString() == "UpArrow")
{
if (x > )//上移不能超过x=8坐标
{
if (map[x - , y] == )//人的下一步只能是空地,或箱子,或墙,先判断空地
{
map[x - , y] = ;
map[x, y] = ; //if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3; x--;
}
else if (map[x - , y] == )//人下一步是终点,走上去的时候照样替换,走之后,就是人下一步是空地的问题了
{
map[x - , y] = ;
map[x, y] = ;
x--;
}
else if (map[x - , y] == && map[x - , y] == )//人的下一步是箱子,箱子的下一步是空地
{
map[x - , y] = ;
map[x - , y] = ;
map[x, y] = ; //if (a[8, 8] != 2 && a[8, 8] != 1)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2 && a[8, 6] != 1)
// a[8, 6] = 3; x--;
}
else if (map[x - , y] == && map[x - , y] == )//人的下一步是箱子,箱子的下一步是终点
{
map[x - , y] = ;
map[x - , y] = ;
map[x, y] = ; //if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3; x--;
}
else //其中包括,人的下一步是墙,箱子的下一步是墙
Console.WriteLine("\a");
}
else
Console.WriteLine("\a");
}
#endregion #region 向下走
if (key.Key.ToString() == "DownArrow")
{
if (x < )//下移不能超过x=8坐标,只能下走增大,给个上限就可以
{
if (map[x + , y] == )//人的下一步只能是空地,或箱子,或墙,先判断空地
{
map[x + , y] = ;
map[x, y] = ;
//if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3;
x++;
}
else if (map[x + , y] == )//解决人不能通过终点坐标问题
{
map[x + , y] = ;
map[x, y] = ;
x++;
}
else if (map[x + , y] == && map[x + , y] == )//人的下一步是箱子,箱子的下一步是空地
{
map[x + , y] = ;
map[x + , y] = ;
map[x, y] = ; //if (a[8, 8] != 2 && a[8, 8] != 1)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子,而且人在终点上的,就让显示人,而不是终点
map[r, s] = ;
//if (a[8, 6] != 2 && a[8, 6] != 1)
// a[8, 6] = 3; x++;
}
else if (map[x + , y] == && map[x + , y] == )//人的下一步是箱子,箱子的下一步是终点
{
map[x + , y] = ;
map[x + , y] = ;
map[x, y] = ; //if (a[8, 8] != 2)
// a[8, 8] = 3;
if (map[r, s] != && map[r, s] != )//当箱子推入终点后,如果人的下一步是空地的话,此时就不能让终点的坐标还显示,而是显示箱子
map[r, s] = ;
//if (a[8, 6] != 2)
// a[8, 6] = 3; x++;
}
else //其中包括,人的下一步是墙,箱子的下一步是墙
Console.WriteLine("\a");
}
else
Console.WriteLine("\a");
}
#endregion MapDisplay(map);
} Console.Write("恭喜你过关!按回车键进入下一关:");
ConsoleKeyInfo key1 = Console.ReadKey();
if (key1.Key.ToString().ToLower() == "enter")
{
a += ;
}
else
{
Console.WriteLine("你输入的有错!");
break;
}
}
} /// <summary>
/// 构造地图
/// </summary>
/// <param name="a">关数</param>
/// <returns>相应关数的地图</returns>
static int[,] Map(int a)
{
int[,] d = new int[, ];
if (a == )
{
int[,] map1 = new int[, ]{
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}}; return map1;
}
else if (a == )
{
int[,] map1 = new int[, ]{
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}}; return map1;
}
else if (a == )
{
int[,] map1 = new int[, ]{
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}}; return map1;
}
else
{
int[,] map1 = new int[, ]{
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,},
{,,,,,,,,,}}; return map1;
}
} /// <summary>
/// 显示地图
/// </summary>
/// <param name="a">传入每一关的地图</param>
static void MapDisplay(int[,] a)
{
Console.Clear();
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
//Console.ForegroundColor = ConsoleColor.White; if (a[i, j] == )
Console.Write("♀");
else if (a[i, j] == )
Console.Write(" ");
else if (a[i, j] == )
{
//Console.ForegroundColor = ConsoleColor.Red;
Console.Write("☆");
// Console.ForegroundColor = ConsoleColor.White;
}
else if (a[i, j] == )
Console.Write("■");
else
Console.Write("□");
}
Console.WriteLine();
}
}//显示地图 /// <summary>
/// 计算人和终点的坐标
/// </summary>
/// <param name="map">每一关的地图</param>
/// <param name="a">a=1 人的坐标,a=2是终点的坐标</param>
/// <param name="b">b=1 x的坐标,b=2 y的坐标</param>
/// <returns>坐标值</returns>
static int ZuoBiao(int[,] map, int a, int b)
{
int m = ;
int[,] aa = map;
if (a == )
{
if (b == )
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (aa[i, j] == )
m = i;
}
}
}
else
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (aa[i, j] == )
m = j;
}
}
}
}
else
{
if (b == )
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (aa[i, j] == )
m = i;
}
}
}
else
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (aa[i, j] == )
m = j;
}
}
}
} return m;
}
eg.3
4、函数递归
递归的几个特点
a、递归式,就是如何将原问题划分成子问题。
b、递归出口,递归终止的条件,即最小子问题的求解,可以允许多个出口。
c、界函数,问题规模变化的函数,它保证递归的规模向出口条件靠拢。
引入非递归
从用户使用角度来说,递归真的很简便,对程序宏观上容易理解。递归程序的时间复杂度虽然可以根据T(n)=T(n-1)*f(n)递归求出,其中f(n)是递归式的执行时间复杂度,一般来说,时间复杂度和对应的非 递归差不多,但是递归的效率是相当低的它主要发费在反复的进栈出栈,各种中断等机制上(具体的可 以参考操作系统)更有甚者,在递归求解过程中,某些解会重复的求好几次,这是不能容忍的,这些也 是引入非递归机制的原因之一。
递归转非递归的两种方法
1.一般根据是否需要回朔可以把递归分成简单递归和复杂递归,简单递归一般就是根据递归式来找出递推公式(这也就引申出分治思想和动态规划)。
2.而复杂递归一般就是模拟系统处理递归的机制,使用栈 或队列等数据结构保存回朔点来求解。
例题:
1.求解阶乘
阶乘的定义就是n!=n*(n-1)! 0!=1 1!=1
根据定义我们很容易就想到递归方法,做法如下
int Fact(int n) {
if(n==) return ; //递归出口
return n*Fact(n-) //n*Fact(n-1)就是递归式,其中n-1就是界函数
}
2.再看Fibonacci的例子
定义:某项的值等于前两项的和,其中第一和第二项为1。
根据定义我们很容易写出程序,这里就不写出来了,当我们用笔划几下的时候我们是否会发现有很多解是重复求出的。举个例子要求F(5)
F(5)=F(4)+F(3);
F(4)=F(3)+F(2);
F(3)=F(2)+F(1);
其中F(3)求解2次。这显然就是时间的浪费。下面我们用递推技术来转化成非递归从例子可以发现我们可以倒过来求解,即从底到顶把F(n)之前要计算的东西保存下来。
程序就是:
int Fibona(int n)
{
int p1=,p2=;
//int a[100]={0};
//a[1]=1,a[2]=1;
for(int i=;i<=n;i++) //从三开始就可以了,后面的return包括1,2
两种情况
{
int r=p1;
//递推,可以使用数组全部保存
p1=p2;
p2+=r;
//a=a[i-1]+a[i-2]
}
return p2;
//return a[n]; }
c# 课堂总结7--函数的更多相关文章
- 前端小课堂 js:函数的创建方式及区别
js 函数的创建大体有这几种方式: -1-函数表达式(函数字面量): 说白了就是把一个函数赋值给了一个变量. var fun1 = function(index){ alert(index); } f ...
- 松软科技课堂:jQuery 事件函数
jQuery 事件函数 jQuery 事件处理方法是 jQuery 中的核心函数. 事件处理程序指的是当 HTML 中发生某些事件时所调用的方法.术语由事件“触发”(或“激发”)经常会被使用. 通常会 ...
- C语言博客作业—嵌套循环
一.PTA实验作业 题目1:7-4 换硬币 1. 本题PTA提交列表 2. 设计思路 (1)定义整型变量money表示待换的零钱总额,p5表示5分硬币的数量,p2表示2分硬币的数量,p1表示1分硬币的 ...
- 机器学习笔记(三)Logistic回归模型
Logistic回归模型 1. 模型简介: 线性回归往往并不能很好地解决分类问题,所以我们引出Logistic回归算法,算法的输出值或者说预测值一直介于0和1,虽然算法的名字有“回归”二字,但实际上L ...
- 二.OC基础--1,对象的存储细节,2,#pragma mark指令,3,函数和对象方法的区别,4,对象和方法之间的关系 ,5.课堂习题
1,对象的存储细节, 1. 当创建一个对象的时候:Person *p1 = [Person new],做了三件事情: 1,申请堆内存空间: 2,给实例变量初始化: 3,返回所申请空间的首地址; 2. ...
- #9.5课堂JS总结#循环语句、函数
一.循环语句 1.for循环 下面是 for 循环的语法: for (语句 1; 语句 2; 语句 3) { 被执行的代码块 } 语句 1 在循环(代码块)开始前执行 语句 2 定义运行循环(代码块) ...
- 网易云课堂_C++开发入门到精通_章节2:引用和函数的高级用法
课时6函数重载 函数重载 在C语言头文件中的extern "C" //常见的C语言头文件格式 #ifndef _FUNC_ #define _FUNC_ #ifdef __cplu ...
- 网易云课堂_程序设计入门-C语言_第五周:函数_2完数
2 完数(5分) 题目内容: 一个正整数的因子是所有可以整除它的正整数.而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数.例如6=1+2+3(6的因子是1,2,3). 现在,你要写一个程序, ...
- 潭州课堂25班:Ph201805201 第九课 函数作用域和匿名函数 (课堂笔记)
匿名函数: lambda obj:str(obj).isdigit 语法规则: lambda 参数:表达式 列: ma1 = map( lambda obj:'binbin','abcdef' ) ...
- 潭州课堂25班:Ph201805201 第八课:函数基础和函数参数 (课堂笔记)
1, 函数定义 def fun(): print('测试函数') fun() #调用函数 return 运行函数返回值 def fun(): name = [1,3,4,5] return name[ ...
随机推荐
- asp导航条子菜单横向
示意图:(代码红色部分为主要.) <%@ Master Language="C#" AutoEventWireup="true" CodeFile=&qu ...
- UVAlive 2326 Moving Tables(贪心 + 区间问题)
The famous ACM (Advanced Computer Maker) Company has rented a floor of a building whose shape is in ...
- 赵雅智:service_startService生命周期
案例演示 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...
- JS获取DropDownList的value值与text值
<script type="text/javascript" language="javascript"> function SearchChang ...
- C#高级编程零散知识点
1.206-实现单链表的添加和插入 207-实现单链表的其他功能和 3.209-Lambda表达式 4.301-栈的介绍和BCL中的栈 4.501-进程和线程的概念[00_12_06][2015122 ...
- Windows下搭建objective C开发环境
摘自:http://blog.csdn.net/zhanghefu/article/details/18320827 最近打算针对iPhone.iPod touch和iPad开发一些应用,所以,需要开 ...
- hdu 4372 第一类stirling数的应用/。。。好题
/** 大意: 给定一系列楼房,都在一条水平线上,高度从1到n,从左侧看能看到f个, 从右侧看,能看到b个,问有多少种这样的序列.. 思路: 因为肯定能看到最高的,,那我们先假定最高的楼房位置确定,那 ...
- (C)单链表
老师版 #include <stdio.h> #include <stdlib.h> // 定于Node数据类型 struct Node { int data; // 数据域 ...
- Microsoft Jet 数据库引擎找不到对象'Sheet1$_'。请确定对象是否存在,并正确地写出它的名称和路径
We have a CRM add-on for Importing Price Lists into CRM. For this tool, we expect the details to be ...
- hibernate 事务的隔离级别 5.1
脏读不可重复读幻读可序列化(符合事务的四个特性的正常情况 ) 解释: 脏读:事务A对数据1做了更新,但是还没有来得及提交 此时事务B对数据1进行了查询获得了事务A更新后的数据, 但是事务A因为一些原因 ...