Java云同桌学习系列(三)——简单输入与数组

本博客java云同桌学习系列,旨在记录本人学习java的过程,并与大家分享,对于想学习java的同学,我希望这个系列能够鼓励大家一同与我学习java,成为“云同桌”。

每章都会从整体框架入手,介绍章节所涉及的重要知识点及相关练习题,并会设置推荐学习时间,每篇博客涉及到的点都会在开篇目录进行总览。(博客中所有高亮部分表示是面试题进阶考点)

学习时间:一周
学习建议:数组是学习集合之前主要的数据存储结构,经常使用,希望能够深入理解,并掌握相关的一些排序算法


1.Scanner类简单用户输入

java中接受用户输入通常使用scanner对象

声明scanner对象:
Scanner scanner = new Scanner(System.in);

调用scanner对象的一些方法可以接收用户输入,各方法分别对应不同的基础数据类型,表格左边为方法的返回值类型

在这里插入图片描述
注意:
scanner.next(),接收用户输入字符串时,会过滤掉有效字符前的无效字符(空格、tab、回车),读取到有效字符后,下一个无效字符视为结束
如:“ abc cdf”只能接收为“abc”

scanner.nextLine()接收的是回车键之前所有的字符串,空格不影响

有时候因为交付标准,不能因为用户输入错误而导致程序崩溃,但有时候必须接受了该类型的数据才能进行某段代码

因此,可以在正式接收数据之前即scanner.next()之前进行判断是什么类型,通过if条件进行限制

scanner.hasNextInt()返回一个布尔型数据,可以作为if的判断条件,限制用户输入的数据类型进入此作用域

if(scanner.hasNextInt()){
 //只有用户输入的数据为int才能执行此代码
}

同理,还有scanner.hasNextFloat(),只有float数据才返回true,等这样对应基础数据类型的方法。

2.一维数组

(1)基本知识

数组:是相同数据类型的多个数据的容器。这些元素按线性顺序排列。所谓线性顺序是指除第一个元素外,每一个元素都有唯一的前驱元素;除最后一个元素外,每一个元素都有唯一的后继元素。

创建数组的方式有:

1int[] num = new int[20];//常用2int[] num = {1,2,3,4,5};//常用3int[] num;    //只创建了数组引用,未创建数组空间4int[] num = new int[]{1,2,3,4,5};//不常用

操作数组中的值是通过数组的下标进行操作,下标由0到n-1,分别对应数组中n个数的值,数组名.length属性返回数组的长度n(不必纠结是声明长度还是有效长度,java中数组被声明后自动将里面的元素有赋成了该数据类型的默认值了)

对于某些算法题里出现的空数组,例:

int[] num = null;

需要注意,一个数据对应一个下标,空数组没有数据,就没有下标,下标0也会造成越界。唉,一言难尽。

(2)数组常见问题

数组越界:
ArrayIndexOutOfBoundsException
常发生于操作时的下标大于数组长度时候报错

空指针异常:
NullPointerException
数组引用没有指向实体,却在操作实体中的元素,或者说操作的数组下标对应的位置没有值,值为null时报错

(3)数组相关问题——冒泡排序

思想:对当前的数据两两比较,根据升降序决定前后位置,每轮数据两两比较完后,会得到一个最大值(在末尾)或最小值(在开头)对n个数据,进行n-1轮内层的比较循环,内层里将对参与该轮的所有数据进行相邻比较,即可将n个数排序

外层循环:控制n个数据的n-1轮内层循环
内层循环:控制该轮的length-i个数据进行length-i-1次相邻比较

代码模块:

public int[] sort_bubble(int[] arr) {             
//冒泡排序
  for(int i = 0;i < arr.length - 1;i++){
                    
   for(int j = 0;j < arr.length - 1 - i;j++){
                           
         if(arr[j] > arr[j + 1]){//这里用了异或
         			//	来不引入第三方变量交换数值
                arr[j] = arr[j]^arr[j+1];
                arr[j+1] = arr[j+1]^arr[j];
                arr[j] = arr[j]^arr[j+1];
          }
                           
     }
                    
   }
    return arr;
}

(4)数组相关问题——数组元素反转

反转即将数组中数的顺序按照反序重新存进去

思想:
将下标0和下标length-1的值,交换;
将下标1和下标length-2的值,交换;
将下标2和下标length-3的值,交换;
将下标3和下标length-4的值,交换;
直到走到了中间同一个位置;

代码模块:

public int[] reverse(int[] arr) {      
           
	for(int i = 0 ,j = arr.length-1 ;i<j ; i++,j--) {
                    
            arr[j] = arr[j]^arr[i];
            arr[i] = arr[i]^arr[j];
            arr[j] = arr[j]^arr[i];
	}
	return arr;
}

(5)数组相关问题——二分法查找

二分法查找的前提:有序数组

二分法查找的思想:

将待查数据与检索范围中间下标数据进行比较
大于中间下标数据,则检索范围在中间下标+1 —— 右边界;
小于中间下标数据,则检索范围在中间下标-1 —— 左边界
逐渐缩小检索范围,直到范围边界重合(左边界==右边界)即找到数据,边界错位(左边界>右边界)即数据不存在
,不论数据在不在范围,只要没有出现在数组中,min就会一直往右走,必定大于max

代码模块:

public int serch_binnary(int num) {             
             //待查找的数,num
             max = arr.length-1;
             min = 0;
             while(true){        
                    mid = (max+min)/2;
                    if(arr[mid]<num) {
                           min = mid+1;
                           
                    }else if(arr[mid]>num) {
                           max = mid -1;
                    }else {
                           System.out.println("该数据在数组中的下标为" + mid);
                           break;
                    }
                    if(min>max) {
                           System.out.println("数据不存在");        
                           break;
                    }      
             }
return mid;
}

(6)数组相关问题——快速排序

快速排序作为最基础的排序算法之一,必然是少不了的,在不少公司笔试的时候,最后一道编程大题,很大概率就是快速排序

快速排序的思想:主要利用的还是分治和递归的思想
即一开始先遍历数组,将大于某个数的放在该数的右边,小于某个数的放在该数的左边,这样就以那个数为边界,分成了两个区域,确定了这两个区域的边界后,进行接下来的递归的排序,对这两个区域再执行上面的步骤即可,直到某个小区域的边界重合或左边界>右边界

代码实例:

import java.util.Scanner;

public class Test {
    public static void main(String[] args)  {

        //输入用户数据
        Scanner scanner = new Scanner(System.in);
        String s = scanner.nextLine();
        String[] temp = s.split(",");
        int[] str = new int[temp.length];

        for(int i = 0;i<temp.length;i++){
            str[i] = Integer.parseInt(temp[i]);
        }

        //调用快排
        int begin = 0;
        int end =str.length-1;
        quick_sort(str,begin,end);

        //输出结果
        for(int i :str){
            System.out.print(i);
        } 

        
    }
    //快排
    public static void quick_sort(int[] str,int begin,int end){

        if(str.length<=1){
            return;
        }
        //左边界>=右边界排序完毕
        if(begin>=end){
            return;
        }
        int l = begin;
        int r = end;

        //标志方向,定义true向左,false向右
        boolean flag = true;
        //边界重合,左右区域划分完毕
        while(l != r){
            if(str[l]>str[r]){
                //交换
                str[l] = str[l]^str[r];
                str[r] = str[r]^str[l];
                str[l] = str[l]^str[r];
                flag = !flag;
            }
            if(flag == true){
                //向左比较
                l++;
            }else{
                //向右比较
                r--;
            }
        }
        //划分完毕子区域,此时l和r指向的即中间边界
        //左边区域
        quick_sort(str, begin, --l);
        quick_sort(str, ++r, end);
    }
}



(7)常见排序算法的时间复杂度

在这里插入图片描述

3.二维数组

首先应该明白一个思想,任何多维数组(维度为n,n>1)都当作一维数组,其数组元素为n-1维数组

从内存中的存放形式来看,数组引用变量是存放在栈内存(stack)中,数组元素是存放在堆内存(heap)中

在这里插入图片描述

数组中存放的大多数是基本数据类型,但也可以存放引用数据类型,当数组元素存放是另一个数组的索引,内存的存放形式便发生了下图的变化
在这里插入图片描述

这样可以把这个二维数组抽象理解成为一个矩阵,宽是一维数组的长度,长是二维数组的长度

那么声明二维数组可以如下声明:

int[][] nums = new int[width][length];
//width指定一维数组的长度,必须有
//length指定每个二维数组的长度,可以没有,每个二维数组的长度可以不一致

那么在访问数据元素的也从num[0]到num[num.length-1],
变成了,nums[0][0]到nums[nums.length-1][[nums.length-1].length-1]

或者在已知二维数组元素的情况下,可以直接赋值,如:

 int[][] arr = {{1,2}, {2, 3}, {4, 5}};

这样相当于建立的是一个int[3][2]的二维数组
一个{}表示结束了一个一维数组的赋值,该大括号里面就是该一维数组对应的二维数组的元素,如{1,2}表示结束了下标为0的一维数组的赋值,该大括号里面 1和2 就是该下标为0的一维数组对应的二维数组的元素。

上图的存储结构可以看做:

1/*arr[0][0]*/	2/*arr[0][1]*/	//arr[0]
2/*arr[1][0]*/	3/*arr[1][1]*/	//arr[1]
4/*arr[2][0]*/	5/*arr[2][1]*/	//arr[2]



都学习到这里了,不妨关注点赞一下~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南窗木心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值