第二阶段-凯发k8官方网
//方法重载:方法名称相同,参数列表不同
//适用性:在不同条件下,解决同一类问题
//优点:让调用者解决一类问题,记忆1个方法。
要求:返回值相同
练习分钟小时的重载
引用参数,为地址,相当于指针。
输出参数类似引用参数,但输出参数在函数中必须修改,调用方法前可以不赋值。
数组读取
练习
录入成绩练习
获取最大值练习
数组写法与练习
计算今年第几天
练习自学array的方法
forreach
:只能读
:全部
依次读取全部元素。
数组简元素进行比较
冒泡排序
缺点:通常交换次数过多。
选择排序(性能提升)
params
意义:简化调用者的调用难度。
形式用法:
调用:
形式:
从下到上,从右到左
声明
从左到右,从上到下
从右到左,从下到上
用法:
arr.length//表示行数*列数;
arr.getength(0);// 行数
arr.getlength(1);// 列数
相关语法
array 数组基类(父类)
object 万类之祖
var 隐式(推断)类型
array的api
特点:参差不齐的数组
长短不一的数组,交错数组的每个元素都是一维数组。
[1][ ][2]
[ ][ ][ ][3][ ]
[ ][ ][4][ ]
创建具有3个元素的交错数组(3行)
int[][] array;
array = new int[3][];--->前边方括号填包括几个一维数组,后边方括号里不能加东西
赋值:
array[0] = new int[3];
array[1] = new int[5];
array[2] = new int[4];
长度可相同。
//将数据1赋值给交错数组的第一个元素的第1个元素
array[0][0] = 1;
array[0][2] = 2;
array[1][2] = 3;
array[2][1] = 4;
读取array:(遍历交错数组)
foreach(var item in array)
{
foreach(var element in item)
{
console.writeline(element);
}
}
//交错数组.length 交错数组元素总数(行数)
//交错数组[索引].length 交错数组元素的元素总数(某一行的列数)
for(int r=0;r
{
for(int c =0;c
{
console.writeline(array[r][c]);
}
}
形式:
float[][] arr3 = new float[3][];
//创建一维数组赋值给交错数组的第一个元素
arr3[0] = new float[2];
arr3[1] = new float[4];
arr3[2] = new float[3];
//将数据1赋值给交错数组的第一个元素的第二个元素
arr3[0][1] = 1;
arr3[1][0] = 2;
arr3[2][2] = 3;
获取所有元素
foreach
foreach (float[] item in arr3)//遍历交错数组的元素(一维数组)
{
foreach (var element in item)//遍历交错数组元素的元素
{
console.writeline(element);
}
}
for
for (int r = 0; r < arr3.length; r )
{
for (int c = 0; c < arr3[r].length; c )
{
console.write(arr3[r][c] "\t");
}
console.writeline();
}
}
arr3.length 交错数组的元素数
arr3[0].length 交错数组第一个元素的元素数
复习
使用params关键字定义的
只能用于形参列表
1.原始
参数数组
正常数组整数相加
整数相加需求//参数个数不确定,类型确定
形式:
static int add(int[] arr)
调用:
int sum =add(new int[]{1,2,3,4,5});
参数数组整数相加
形式:
整数相加需求//参数个数不确定,类型确定
static int add(params int[] arr)
调用:
int sum =add(1,2,3,4,5);
对于调用者来说更方便,对于方法内部而言,就是普通一维数组
整数相加的方法:(个数不确定,类型能确定)
用到params的数组要放在形参最后面, add(int a,params int[] arr)
private static int add(params int[] arr)【params 可以使调用者直接传递一组数据类型相同的变量集合,也可以不传】
{
int sum;
for(int i =0;i
{
sum =arr[i];
}
}
foreach也可,因为foreach只对自身只读,这里是sum 变化,foreach不变化
main()
{
//int a=add(new int[]{1,2,3,4,5});
int a = add(1,2,3,4,5);---->用了params 就不用再new int[]
int b = add();--->用了params也可以不传
}
复习
答案
private static void main2()
{
int[] myticket = buyticket();
console.writeline("我买的彩票:");
printticket(myticket);
console.writeline("验证我的中奖潜力……");
int count = 0;
int level;
do
{
count ;
int[] ticket = createticket();
//购买彩票与开奖彩票对比
level = ticketequals(myticket, ticket);
console.writeline("*********开奖号码:*********");
printticket(ticket);
if (level != 0)
console.writeline("恭喜,{0}等奖。累计花费:{1}元", level, count * 2);
} while (level != 1);
}
private static int[] buyticket()
{
int[] ticket = new int[7];
for (int i = 0; i < ticket.length - 1; )
{
console.writeline("请输入第{0}个红球号码:", i 1);
int rednumber = int.parse(console.readline());
if (rednumber < 1 || rednumber > 33)
console.writeline("您输入的数字超过红球号码范围:1--33");
//[重点:判断输入的号码在数组中是否存在]
else if (array.indexof(ticket, rednumber) >= 0)
console.writeline("当前数字已经存在,请重新录入");
else
ticket[i ] = rednumber;
}
int bluenumber;
do
{
console.writeline("请输入篮球号码:");
bluenumber = int.parse(console.readline());
if (bluenumber >= 1 && bluenumber <= 16)
ticket[6] = bluenumber;
else
console.writeline("请输入数字超过篮球号码:1--16");
} while (bluenumber < 1 || bluenumber > 16);//数字不在1--16之间 再次执行
return ticket;
}
private static random ran = new random();
private static int[] createticket()
{
int[] ticket = new int[7];
//[重点:生成多个不重复的随机数]
for (int i = 0; i < 6; )
{
//思路:生成随机数,判断是否存在,不在则存储
int num = ran.next(1, 34);
if (array.indexof(ticket, num) == -1)
ticket[i ] = num;
}
ticket[6] = ran.next(1, 17);
//红球号码排序[重点:指定范围的排序]
array.sort(ticket, 0, 6);
return ticket;
}
private static int ticketequals(int[] myticket1, int[] ranticket2)
{
//判断红球号码中奖数量
//思路:我的第1个号码在随机彩票的红球号码段中是否存在
// 我的第2个号码在随机彩票的红球号码段中是否存在
//[重点:在指定范围内检查是否具有相同元素]
int redcount = 0;
for (int i = 0; i < 6; i )
{
if (array.indexof(ranticket2, myticket1[i], 0, 6) != -1)
redcount ;
}
int bluecount = myticket1[6] == ranticket2[6] ? 1 : 0;
int level;
if (redcount bluecount == 7)
level = 1;
else if (redcount == 6)
level = 2;
else if (redcount bluecount == 6)
level = 3;
else if (redcount bluecount == 5)
level = 4;
else if (redcount bluecount == 4)
level = 5;
else if (bluecount == 1)
level = 6;
else
level = 0;
return level;
}
private static void printticket(int[] ticket)
{
for (int i = 0; i < ticket.length; i )
{
console.write(ticket[i] "\t");
}
console.writeline();
}
图片
代码
//缺点:通常交换次数过多。
private static int[] orderby1(int[] array)
{
//1.取数据
for (int r = 0; r < array.length - 1; r )
{
//2.比较
for (int c = r 1; c < array.length; c )
{
//3.发现更小则交换
if (array[r] > array[c])
{
int temp = array[r];
array[r] = array[c];
array[c] = temp;
}
}
}
return array;
}
图片
代码
private static int[] orderby(int[] array)
{
//1.取数据
for (int r = 0; r < array.length - 1; r )//轮
{
//2.查找最小索引
int minindex = r;//假设下当前元素就是最小索引
for (int c = minindex 1; c < array.length; c )//次
{
//发现更小的元素
if (array[minindex] > array[c])
{
//记录位置(替换假设的最小索引)
minindex = c;
}
}
//3.交换
if (minindex != r)
{
int temp = array[minindex];
array[minindex] = array[r];
array[r] = temp;
}
}
return array;
}
//*******************2048核心算法*****************************************
/*需求分析1.0
1.向上移动
--- 获取列数据,形成一维数组
* --- 去除零元素(将非零元素向前移动)
* ---合并数据
* -- 如果相邻元素相同
* -- 将后一个元素累加到前一个元素上
* -- 将后一个元素清零
* --- 去除合并过程中产生的零元素(将非零元素向前移动)
* --- 还原列数据
*
2.向下移动
--- 获取列数据,形成一维数组
* --- 去除零元素(将非零元素向后移动)
* ---合并数据
* -- 如果相邻元素相同
* -- 将前一个元素累加到后一个元素上
* -- 将前一个元素清零
* --- 去除合并过程中产生的零元素(将非零元素向后移动)
* --- 还原列数据
*
需求分析2.0
1.向上移动
--- 获取列数据(从上到下),形成一维数组
--- 调用合并数据方法
* --- 还原列数据(从上到下)
*
2.向下移动
--- 获取列数据(从下到上),形成一维数组
--- 调用合并数据方法
* --- 还原列数据(从下到上)
*
3.合并数据
* --- 调用去除零元素
* ---合并数据
* -- 如果相邻元素相同
* -- 将后一个元素累加到前一个元素上
* -- 将后一个元素清零
* --- 调用去除零元素
4.去零方法(将非零元素向前移动)
*/
答案
移动零
private static void removezero(int[] array)
{
//创建新数组0 0 0 0
int[] newarray = new int[array.length];
int newindex = 0;//新数组索引
//将参数中非零元素,依次存入新数组2 2 2 0
for (int i = 0; i < array.length; i )
{
if (array[i] != 0)
{
newarray[newindex ] = array[i];// 存入 自增
}
}
//返回新数组
//return newarray;
//array = newarray;//修改栈中引用
newarray.copyto(array, 0); //拷贝元素 array[0] = newarray[0];
}
合并相同项
private static void merge(int[] array)
{
removezero(array);//2 0 2 2 --> 2 2 2 0
//合并数据
for (int i = 0; i < array.length-1; i )
{
//非零 且 相邻相同
if (array[i] !=0 && array[i] == array[i 1])
{
array[i] = array[i 1];
array[i 1] = 0;
}
}
removezero(array);
//return array;
}
向上移动
private static void moveup(int[,] map)
{
int[] mergearray = new int[map.getlength(0)];
for (int c = 0; c < map.getlength(1); c )
{
//00 10 20 30
for (int r = 0; r < map.getlength(0); r )//从上到下 获取列数据
mergearray[r] = map[r, c];
merge(mergearray);
for (int r = 0; r < map.getlength(0); r )//从上到下 还原列数据
map[r, c] = mergearray[r];
}
//return map;
}
向下移动
private static void movedown(int[,] map)
{
int[] mergearray = new int[map.getlength(0)];
for (int c = 0; c < map.getlength(1); c )
{
//30 20 10 00
for (int r = map.getlength(0) - 1; r >= 0; r--)
mergearray[3 - r] = map[r, c];//正向存入一维数组
merge(mergearray);
for (int r = map.getlength(0) - 1; r >= 0; r--)
map[r, c] = mergearray[3 - r];
}
//return map;
}
输出显示
private static void printmap(int[,] map)
{
for (int r = 0; r < map.getlength(0); r )
{
for (int c = 0; c < map.getlength(1); c )
{
console.write(map[r, c] "\t");
}
console.writeline();
}
}
//移动 move(1 , map)
//导医
移动
private static void move(int direction,int[,] map)
{
switch (direction)
{
case 0:
moveup(map);
break;
case 1:
movedown(map);
break;
}
}
//目的:让2048算法使用者,可以只记忆一个move方法。
移动重写
private static void move(movedirection direction, int[,] map)
{
switch (direction)
{
case movedirection.up:
moveup(map);
break;
case movedirection.down:
movedown(map);
break;
}
}
主函数
static void main()
{
int[,] map = new int[4, 4]
{
{ 2,4,0,4 },
{ 0,2,2,4 },
{ 2,0,0,2 },
{ 4,2,2,0 }
};
printmap(map);
console.writeline("向上移动");
//moveup(map);//用户需要记忆的方法过多
//move(0, map);//用户输入的方向不明确
move(movedirection.up, map);//限定了取值范围
printmap(map);
console.writeline("向下移动");
//movedown(map);
move(movedirection.down, map);
printmap(map);
}
类型图示
值类型和引用类型图示
int[] arr;//在栈中声明。a为位地址
arr= new int[]{1}
没有【】就是改栈(重新开辟空间,附地址),有就是改堆。
string a="1"
string b=a
b="5"
得
s2="1"
面试:stringbuilder与string的区别于优越性差异
应用1:赋值
图示
代码
static void main3()
{
//方法执行在栈中
//方法内部声明的变量,都在栈中分配空间。
int a;//在栈中
a = 1;//数据1在栈中( 因为值类型直接存数据 )
int b = a;//a将存储的数据赋值b
a = 2;//修改栈中存储的数据
console.writeline(b);//?
//arr:数组的引用
int[] arr;//在栈中
arr = new int[] { 1 };//数组对象在堆中(引用类型数据在堆中)
int[] arr2 = arr;//arr将存储的引用赋值给arr2
//arr[0] = 2;//修改堆中存储的数据(数组对象)
arr = new int[] { 2 };//修改栈中存储的引用
console.writeline(arr2[0]);//?
string s1 = "老王";
string s2 = s1;//s1将存储的引用赋值给s2
s1 = "老宋";//修改栈中存储的引用,重新开辟空间存储"老宋",替换栈中引用
console.writeline(s2);//?
object o1 = 100;
object o2 = o1;//将o1存储的引用赋值给o2
o1 = 200;//修改栈中存储的引用,重新开辟空间存储200,替换栈中引用
console.writeline(o2);//?
}
应用2:比较
图示
代码
static void main4()
{
//值类型存数据,比较数据
int a = 1, b = 1;
bool r1 = a == b;//比较数据1
console.writeline(r1);//true
//引用类型存引用,比较引用
int[] arr01 = { 1 }, arr02 = { 1 };
bool r2 = arr01 == arr02;//比较数组引用
bool r3 = arr01[0] == arr02[0];//比较数组元素
console.writeline(r2);//?
}
应用3:传参
图示
代码
static void main5()
{
int a1 = 1;
int[] arr1 = { 1 };
fun1(a1, arr1);//a1将存储的数据1、arr1将存储的引用 传入方法
console.writeline(a1);//?1
console.writeline(arr1[0]);//?2
int a2 = 1;
fun2(ref a2);//将a2自身地址传入方法
console.writeline(a2);//2
//区别2:输出参数进入方法前可以不赋值
int a3;//意图:接收方法的结果
fun3(out a3);//将a2自身地址传入方法
console.writeline(a3);//2
}
方法参数:值参数、引用参数、输出参数
根据传递方式进行的划分。
值参数:按值传递 --- 传递实参变量所存储的内容
作用:传递信息
局部变量:在栈中,全局变量,不在
方法内种局部变量,为
private static void fun1(int a,int[] arr)
{
//结论:引用类型,方法内部修改堆中数据,影响实参。
a = 2;
arr[0] = 2;//堆中数据
//arr = new int[] { 2 };//修改栈中引用
}
引用参数:按引用传递 --- 传递实参变量自身引用(内存地址)
//作用:改变数据
private static void fun2(ref int a)
{//方法内部修改形参,等同于修改实参
a = 2;
}
输出参数:按引用传递 --- 传递实参变量自身引用(内存地址)
//作用:返回结果
private static void fun3(out int a)
{//区别1:方法内部必须修改输出参数
a = 2;
}
static void main6()
{
int num01 = 1, num02 = 2;
swopnumber(ref num01, ref num02);
int area,per;
calculaterect(10, 20, out area, out per);
string input = console.readline();
//int atk = int.parse(input);
//尝试着转换,如果成功通过输出参数返回结果。
// 如果失败,可以通过返回值获取结果。(木有异常)
int result;
if (!int.tryparse(input, out result))
{
console.writeline("失败喽");
}
}
应用练习
交换两个整数
矩形面积
面试:发生拆装箱的数目
例子:
ilspy
没有拆装箱,int number…….
concat字符串拼接,本质是由concat,装箱。。。。。。结局方案。.tostring
int->object形参为object
如果形参object,实参值类型,产生装箱操作。
凯发k8官方网的解决方案
1.
2.泛型:可以将数据类型作为参数传入。
private static void fun2
}
调用:fun2
//如果形参object类型,实参值类型。会产生装箱操作。
//凯发k8官方网的解决方案:1.重载 2.泛型:可以将数据类型作为参数传入方法。
特性1:字符串池(字符串常量)
// 节省内层
string s1 = "老王";
string s2 = "老王";
//s1 / s2 是同一对象
string s3 = new string(new char[] { '老', '宋' });
string s4 = new string(new char[] { '老', '宋' });
//s3 / s4 不是同一对象
特性2:不可变性
// 如果可变,就会破坏其他对象的内存空间
string s5 = "张飞";
s5 = "夏军军";//重新开辟空间 存储新字符串,替换栈中引用。
//s5[0] = '夏';
char c1 = s5[0];
console.writeline(s5);//? "张飞" -改变-> "夏军"
string s6 = "老";
string s7 = s6 "王";//"老王" 与 s1/s2 不是同一对象 "字符串变量参与的拼接,没有使用字符串池的特性"
string s8 = string.empty;//""
for (int i = 0; i < 10; i )
{
//每次拼接都会产生一个新对象,产生1个垃圾
s8 = s8 i.tostring();
//"" "0"
//"0" "1"
//"01" "2"
}
console.writeline(s8);//?
可变字符串
string和stringbuilder的优缺点
总结
以上是凯发k8官方网为你收集整理的第二阶段_第四家小节_c#基础2的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 第二阶段_第三小节_c#基础
- 下一篇: 第二阶段_第五小节_c#基础3