C# Array进阶

数组的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
​
namespace _02_数组的方法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int[] ints1 = { 1, 2, 3 ,4,5,6,7};
​
        //将数组中指定的数据恢复为对应数据类型的默认值
        //参数1: 需要恢复的数组
            参数2:开始的索引
            //参数3:恢复的个数
            //Array.Clear(ints1, 2, 4);//{1,0,0,0,0,6,7,}
            WriteArr(ints1);
​
​
​
            int[] ints2 = new int[10];
​
            //将参数1数组 复制到参数2数组中,由参数3决定复制的个数
            //注意:1.复制的个数不能超过源数组的长度
            //2.复制的个数不能超过新数组的长度
            Array.Copy(ints1, ints2, 6);
            WriteArr(ints2);//{1,2,3,4,5,6,0,0,0,0,}
​
            //复制是数组中的数据,这是两个不同的数组,不会互相影响
            ints1[0] = 100;
            Console.WriteLine(ints2[0]);
​
​
            //===========================
​
            //数组里面保存的仅仅是引用类型的内存地址
            //复制仅仅是数组中的数据
​
            People[] peoples1 = {
                new People() { Name = "吴亦凡" }
            };
​
            People[] peoples2 = new People[2];
​
            //复制的仅仅是内存地址
            Array.Copy(peoples1, peoples2, peoples1.Length);
      
            //复制出来的内容,和原始内容,指向的是同一个内存地址,所以一个改变,会影响另一个
            peoples2[0].Name = "罗志祥";
            Console.WriteLine(peoples1[0].Name);//罗志祥
​
​
            //----------------
​
​
           int[] ints3 = {2,4,5,6,7,8,9};
           int[] ints4 = new int[6];
           /*
            * 参数1:被复制的数组
            * 参数2:复制的开始的位置
            * 参数3:复制到的目标数组
            * 参数4:目标数组的开始位置
            * 参数5:复制的个数
            */
            Array.Copy(ints3, 2,ints4, 1,4);
            WriteArr(ints4);//{0,5,6,7,8,0,
​
            //反转数组
            Array.Reverse(ints3);
            WriteArr(ints3);//{ 9,8,7,6,5,4,2,}
            //从前向后查找参数2数据,在参数1数组中首次出现的位置,有则返回数据的索引位置,没有则返回-1
            Console.WriteLine(Array.IndexOf(ints3,15));
​
            //参数3是指定开始查询的位置
            Console.WriteLine(Array.IndexOf(ints3, 5,5));
            //参数4:指定查询的个数
            //从ints3中查询5 从索引2的位置开始 查询3个值
            Console.WriteLine(Array.IndexOf(ints3, 5, 2,3));
            //从后向前查找参数2数据,在参数1数组中首次出现的位置,有则返回数据的索引位置,没有则返回 - 1
            Console.WriteLine(Array.LastIndexOf(ints3, 5, 2, 3));
​
​
            //---------------以上这些是普通函数----------------------
​
​
            //高阶函数(高级函数)
​
​
​
            int[] ages = { 34, 12, 28, 18, 24, 15 };
​
            //需求:查询数组中第一个年龄为18的索引
            //Console.WriteLine(Array.IndexOf(ages,18));
            //IndexOf() 可以进行等值查询 但是不能进行范围查询
            //需要对数组中的数据,进行范围查询,IndexOf() 不能满足需求
            //比如: 查询数组中第一个不满足18的数字
​
​
​
​
            //Find() 根据传入的数组和方法,从前向后查询,返回第一个满足条件(传入的函数)的数据
            //Find() 的工作原理:循环该数组,并且每次循环调用传递的函数,并且将当前的数据通过参数传递到方法中,如果方法返回了true,则Find直接返回当前这个参数
            //参数1:查询的数组
            //参数2:一个函数,这个函数需要返回一个布尔值,表示当前数值是否满足条件,
            //如果当前数组中没有满足条件的数组,则返回该类型的默认值
            //高阶函数:参数也是一个函数
            //回调函数:以参数的形式传递到函数中的函数
            Console.WriteLine(Array.Find(ages, FinSmall18));
​
​
            //需求:返回数组中第一个奇数
            Console.WriteLine(Array.Find(ages, FinOdd));
​
            //需求:返回数组中第一个能够被3和5有同时整除的数字
            Console.WriteLine(Array.Find(ages, Fin35));
​
​
            string[] strings = { "21wewqe", "发生的hi发的红四方", "FDD是符合度" };
​
            //因为没有字符串满足条件,所以返回值的是null(当前数据类型的默认值)
            Console.WriteLine(Array.Find(strings, Find3));//null
​
            //string s = "";
            //string s = null;
            //string s=string.Empty;
            Console.WriteLine(string.IsNullOrEmpty(Array.Find(strings, Find3)));
​
​
​
            //FindIndex() 根据传入的数组和方法,从前向后查询,返回一个满足条件的数据的索引
            Console.WriteLine(Array.FindIndex(ages,FinSmall18));
            Console.WriteLine(Array.FindIndex(ages, FinOdd));
            Console.WriteLine(Array.FindIndex(ages, Fin35));
​
            //FindLast() 根据传入的数组和方法,从后向前查询,返回第一个满足条件的数据
            Console.WriteLine(Array.FindLast(ages, Fin35));
            // FindLastIndex() 根据传入的数组和方法,从后向前查询,返回一个满足条件的数据的索引
            Console.WriteLine(Array.FindLastIndex(ages, Fin35));
​
​
            // FindAll() 返回所有满足条件的数据
            int[] arr=   Array.FindAll(ages, FinSmall18);
​
​
​
            int[] nums = { 11, 12, 13 };
            //判断数组中的数据是否全部都是偶数
​
            //TrueForAll() 判断数据中数据是否全部都满足条件(如果所有的数据都满足条件,则返回true,有一个不满足条件就返回false)
            Console.WriteLine(Array.TrueForAll(nums,FnEven));
            //Exists() 判断数组中是否至少有一个满足条件(一个满足条件,就返回true,所有的都不满足,则返回false)
            Console.WriteLine(Array.Exists(nums, FnEven));
​
            //用于循环数组
            Array.ForEach(ages, Each);
​
​
            //---以上这些方法,都是Array类上的方法,需要使用Array.xxx调用---------------
​
​
            //-----以下这些方法,都是Array实例上的方法,需要使用 实例(数组).xxx调用
​
            string[] str1 = { "吴亦凡", "罗志祥", "李云迪" };
            string[] str2 = new string[5];
            str1.CopyTo(str2, 1);
             //将str1复制到str2中,从str2的索引为1的位置开始放
            WriteArrStr(str2);  //{null,吴亦凡,罗志祥,李云迪,null}
​
            int[,,] ints6 = new int[10, 5, 4];
            Console.WriteLine(ints6.GetLength(0));//第一个维度的长度
            Console.WriteLine(ints6.GetLength(1));//第二个维度的长度
​
​
            //等同于: str1[0] = "李云迪";
            str1.SetValue("李云迪", 0);
            Console.WriteLine(str1.GetValue(0));
            Console.WriteLine(str1.Contains("李云迪"));
            //str1.All() ====> Array.TrueForAll();
            //str1.Any() ====> Array.Exists();
​
​
​
​
        }
​
        /// <summary>
        /// 自定义的函数,为了演示数组经过一系列api的操作之后的效果
        /// </summary>
        /// <param name="arr"></param>
        /// <returns></returns>
        public static string WriteArr(int[] arr)
        {
            string s = "{";
            for (int i = 0; i < arr.Length; i++)
            {
                s+= arr[i]+",";
            }
            s += "}";
            Console.WriteLine(s);
            return s;
        }
        public static string WriteArrStr(string[] arr)
        {
            string s = "{";
            for (int i = 0; i < arr.Length; i++)
            {
                s += arr[i] + ",";
            }
            s += "}";
            Console.WriteLine(s);
            return s;
        }
​
​
​
        public static bool FinSmall18(int value)
        {
            Console.WriteLine("value==="+value);
            //if (value<18)
            //{
            //    return true;
            //}
            //else
            //{
            //    return false;
            //}
​
​
            return value < 18;
​
        }
​
        public static bool FinOdd(int value)
        {
            return value % 2 != 0;
        }
        public static bool Fin35(int value)
        {
            return value % 3 == 0 && value % 5 == 0;
        }
        public static bool Find3(string value)
        {
            return value.Length < 3;
        }
​
        public static bool FnEven(int value)
        {
            return value % 2 == 0;
        }
        public static  void Each(int value)
        {
            Console.WriteLine(value);
        }
​
    }
    class People
    {
        public string Name;
    }
}
​

lambda表达式

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
​
namespace _03_lambda表达式
{
    internal class Program
    {
        static void Main(string[] args)
        {
​
            Write();//如果代码块中内部和外部有相同的方法,优先调用内部的方法
​
            
            //函数不仅可以定义在类中,还可以定义在方法中
            //格式: 返回值类型  函数名(形参){函数内容}
            void Write()
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.WriteLine("李云迪");
                }
            }
​
​
            //需求: 定义函数 求两个数的和
​
            int Sum(int a,int b)
            {
                return a + b;
            }
​
            Console.WriteLine(Sum(10,20));
​
​
​
​
            //int[] ints = { 1, 2, 3, 4, 5, 6 };
​
​
            //查找数组中第一个偶数
            //Console.WriteLine(Array.Find(ints, FindEven));
​
            //bool FindEven(int value)
            //{
            //    return value % 2 == 0;
            //}
​
            //Lambda 表达式用于创建一个函数(箭头函数)
            //本质上就是一个匿名函数(没有名字的函数) 
            //具名函数(有名字函数)
​
​
            //格式:  Func<参数1的类型,参数2的类型,返回值类型> FnName1 =(参数1,参数2)=>{函数的内容}
            Func<int,int,bool> FnName1  = (int a, int b) =>
            {
                return a > b;
            };
​
            //调用的时候,和普通的函数相同
            Console.WriteLine(FnName1(10,20));
​
​
            //1.函数的实现中,参数的类型可以省略
            Func<int, int, bool> FnName2 = (a,  b) =>
            {
                return a > b;
            };
​
            //2.如果只有一个参数 可以省略()
            Func<int, bool> FnName3 = a =>
            {
                return a % 2==0;
            };
​
​
            //3.如果函数中只有一个表达式, 可以省略{}和return,他会自动返回表达式运行的结果
            Func<int, bool> FnName4 = a => a % 2 == 0;
            //以下这行代码和57行代码等价
            Func<int, int, bool> FnName5 = (a, b) => a > b;
​
​
​
            int[] ints = { 1, 2, 3, 4, 5, 6 };
​
​
            //查找数组中第一个偶数
            Console.WriteLine(Array.Find(ints, v => v % 2 == 0));
​
            //bool FindEven(int value)
            //{
            //    return value % 2 == 0;
            //}
​
​
            Func<int,bool> FindEven= v =>v % 2 == 0;
​
            int[] ages = { 34, 12, 28, 18, 24, 15 };
​
​
            //需求:查询数组中第一个不满足18的数字
            Console.WriteLine(Array.Find(ages,v=>v<18));
​
             //需求: 返回数组中第一个奇数
           Console.WriteLine(Array.Find(ages, v => v %2 !=0 ));
​
​
        }
​
        public static void Write()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("吴亦凡");
            }
        }
        public static bool FindEven(int value)
        {
            return value % 2 == 0;
        }
    }
}
​

数组排序

冒泡排序

冒泡排序,Bubble Sort 一个简单且常用的排序算法。因最大或最小的元素会经过交换慢慢出现在数列顶端,好似元素冒出来一样,得名“冒泡排序”。

原理

1.比较相邻的元素,若第一个比第二个大则交换他们两个。

2.对每一组相邻的元素做同样的工作(从开始的第一对到最后的最后一对)。

3.针对除最后一个元素外的所有元素重复以上的步骤。

4.重复对未定位到合适位置的元素操作上述步骤直至排序完成。

  冒泡排序
  将数组每一位和相邻的另一位进行对比,如果右边的更小,则进行交换
  //int[] ints1 = { 6, 5, 4, 3, 1,2};
   外层循环执行一次 内层循环就执行全部  外层循环执行 6 内层循环 5
   需要 5*6  30次才能把数组排序好
  //for (int i = 0; i < ints1.Length; i++)
  //{
  //    //-1的原因: 如果最后不-1,最后一次循环 ints1[6] ===7 ints1[6+1] 索引越界
  //    for (int j = 0;j < ints1.Length-1; j++)
  //    {
  //        //相邻的元素进行比较,如果前一个值比后一个值大,交换位置
  //        if (ints1[j] > ints1[j+1])
  //        {
  //            //不使用语法糖
  //            int temp = ints1[j];
  //            ints1[j] = ints1[j+1];
  //            ints1[j+1] = temp;
​
  //        }
​
  //    }
  //}
​
  //----------------优化--------------------
  int[] ints1 = { 6, 5, 4, 3, 1, 2 };
 
  for (int i = 0; i < ints1.Length; i++)
  {
      //-1的原因: 如果最后不-1,最后一次循环 ints1[6] ===7 ints1[6+1] 索引越界
      //-i的原因: 减去已经排序号的数字,外层循环执行一次,就多了一个排序好的数字
      // ints1.Length - 1-i 让内层循环每循环一次 就少一次
      //5+4+3+2+1=15
      for (int j = 0; j < ints1.Length - 1-i; j++)
      {
         
          if (ints1[j] > ints1[j + 1])
          {
​
              (ints1[j], ints1[j + 1]) = (ints1[j + 1], ints1[j]);
             
          }
​
      }
  }

选择排序

选择排序在要排序的一组数中,选出最小(或最大)的一个数与第一个位置的数交换;在剩下的数当中找最小的与第二个位置的数交换,即顺序放在已排好序的数列的最后,如此循环,直到全部数据元素排完为止

原理
  1. 先从数组中选出一个最小的元素,将其与数组首元素交换位置

  2. 从剩下的n-1个元素中选出最小的元素,将其与数组的第二个元素交换位置

  3. 从剩下的n-2个元素中选出最小的元素,将其与数组的第三个元素交换位置

  4. 以此类推,直到剩下的元素个数为0

​
            for (int i = 0; i < ints1.Length; i++)
            {
                //找到最小值的索引
              int minNumPost=  FindMinPos(ints1,i);
              (ints1[i], ints1[minNumPost]) = (ints1[minNumPost], ints1[i]);
                
            }
 public static int FindMinPos(int[] arr ,int startIndex)
 {
​
     //声明一个变量记录最小值
     //默认值设置为负无穷 
     double minNum = double.PositiveInfinity;
     int minIndex = -1;
​
     for (int i = startIndex; i < arr.Length; i++)
     {
         if (arr[i]<minNum)
         {
             minNum = arr[i];
             minIndex = i;
         }
     }
​
​
     return minIndex;
 }

选择排序和冒泡排序的区别

  • 冒泡排序将最大的元素逐渐后移,选择排序将最大的元素直接右移

  • 每次循环时,冒泡排序会将大的元素逐渐后移,选择排序只会将最大的元素直接右移

  • 排序后,冒泡排序不会改变相同元素的相对次序,选择排序会改变

Sort()函数

  // Array 类有一个Sort()函数, 用于数组的排序,(默认是正序(升序)排列)
  //升序:从小到大
  //降序:从大到小
  //Array.Sort(ints1);
  //Array.Reverse(ints1);
​
​
  Array.Sort(ints1, (x,y) =>
  {
      //如果小于   0 则x小于y
      //如果为0    则x等于y
      //如果大于   0 则 x大于y 
​
​
      //if (x < y) return -1;
      //if (x > y) return 1;
      //return 0;
​
​
      //if (x < y) return 1;
      //if (x > y) return -1;
      //return 0;
      //return  x-y; //正序
      return y - x; //倒序
  });
​
  //正序
  Array.Sort(ints1,(a,b)=>a-b);
  Array.Sort(ints1, (a, b) => b - a);
  //二分法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值