一把刀的锋刃很不容易越过;因此智者说得救之道是困难的
--印度《吠陀经》
一、二维数组
1、概念
学校的班每个班有很多个学生,所以,可以用数组来存储,而我们又同时有很多个大数据班。这个也应该用一个数组来存储。如何来表示这样的数据呢?Java就提供*了二维数组供我们使用。
由此可见:其实二维数组其实就是一个元素为一维数组的数组。
2、格式
(1)格式1:
数据类型[][] 变量名 = new 数据类型[m][n];
- m表示这个二维数组有多少个一维数组
- n表示每一个一维数组的元素个数
举例:
int[][] arr = new int[3][2];
//定义了一个二维数组arr 这个二维数组有3个一维数组;
//名称是arr[0],arr[1],arr[2] 每个一维数组有2个元素;
//可以通过arr[m][n]来获取 表示获取第m+1个一维数组的第n+1个元素;
(2)格式2:
数据类型[][] 变量名 = new 数据类型[m][];
- m表示这个二维数组有多少个一维数组
- 这一次没有直接给出一维数组的元素个数,可以动态的给出。
举例:
int[][] arr = new int[3][];
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
(3)格式3:
数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}};
简化版格式:
数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
举例:
int[][] arr = {{1,2,3},{4,6},{6}};
二、冒泡排序
1、概念
气泡排序(Bubble Sort)是一种简便而直接的排序方法。它反复访问待分类的序列,每次对两个元素进行比较,如果它们的次序不对,则将它们调换。对序列的访问一直在不断地进行,直到没有更多的交换需求,这意味着序列已经被完成了。该算法之所以得名,是由于较小的元素通过交换而逐渐"浮"到了序列的顶部。
2、原理
冒泡排序就是从序列中的第一个元素开始,依次对相邻的两个元素进行比较,如果前一个元素大于后一个元素则交换它们的位置。如果前一个元素小于或等于后一个元素,则不交换它们;这一比较和交换的操作一直持续到最后一个还未排好序的元素为止。
3、图解
三、二分法
1、概念
在数学中--二分法(Bisection method) 即一分为二的方法. 设[a,b]为R的闭区间. 逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点。
将这条数学思想带入计算机就可以获得在计算机中的二分法编程思想:
- 假设数据是按升序排序的,对于给定值key,从序列的中间位置k开始比较,
- 如果当前位置arr[k]值等于key,则查找成功;
- 若key小于当前位置值arr[k],则在数列的前半段中查找,arr[low,mid-1];
- 若key大于当前位置值arr[k],则在数列的后半段中继续查找arr[mid+1,high]
2、原理
二分法(又称为二分搜索)被定义为一种在排序数组中使用的搜索算法,通过重复将搜索间隔一分为二。二分查找的思想是利用数组已排序的信息,将时间复杂度降低到O(log N)。
需要注意
- 数据结构必须是有序的。(在我所学习的Java中可以将数组与前文中的冒泡排序相结合来获取有序的数据结构,将会在后面的练习中体现)
- 访问数据结构的任何元素都需要恒定的时间。
3、图解
- 将搜索空间的中间元素与键进行比较。
- 如果在中间元素找到密钥,则过程终止。
- 如果在中间元素没有找到键,则选择哪一半将用作下一个搜索空间
- 如果键小于中间元素,则使用左侧进行下一步搜索。
- 如果键大于中间元素,则使用右侧进行下一步搜索。
- 这个过程一直持续到找到密钥或者总搜索空间耗尽为止。
四、练习题目
如果想进行练习,请先自主思考,答案放在文章的最后(注意作者的代码十分冗余,仅作参考使用!!!)(可以看看思路,因为是半路出家的,很多知识点并没有了解,直接可以从思路中学习,不需要再费时寻找相关知识点)
-- 1、数组查找操作:定义一个长度为10 的一维字符串数组,在每一个元素存放一个单词;然后运行时从命令行输入一个单词,程序判断数组是否包含有这个单词,包含 这个单词就打印出“Yes”,不包含就打印出“No”。
-- 2、数组逆序操作:定义长度为10的数组,将数组元素对调,并输出对调前后的结果。
思路:
把0索引和arr.length-1的元素交换,把1索引和arr.length-2的元素交换…..
只要交换到arr.length/2的时候即可。
-- 3、合并数组操作:现有如下一个数组: int oldArr[]={1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5} 要求将以上数组中值为0的项去掉,将不为0的值存入一个新的数组,生成的新数组为: int newArr [] ={1,3,4,5,6,6,5,4,7,6,7,5}
思路: 确定出不为0的个数,这样可以开辟新数组;从旧的数组之中,取出内容, 并将其赋给新开辟的数组。如果判断到0,就使用continue关键字。
-- 4、二分法查找操作:使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。
分析:
假如有一组数为3,12,24,36,55,68,75,88要查给定的值24.可设三个变量
front,mid,end分别指向数据的上界,中间和下界,mid=(front+end)/2.
1)开始令front=0(指向3),end=7(指向88),则mid=3(指向36)。因为mid>x,故应在前半段中查找。
2)令新的end=mid-1=2,而front=0不变,则新的mid=1。此时x>mid,故确定应 在后半段中查找。
3)令新的front=mid+1=2,而end=2不变,则新mid=2,此时a[mid]=x,查找成功。如要查找的数不是数列中的数,例如x=25,当第三次判断时,x>a[mid],按以上规律,令front=mid+1,即front=3,出现front>end的情况,表示查找不成功。
-- 5、二维数组遍历求和操作:用二重循环求出二维数组b所有元素的和int[][] b={{11},{21,22},{31,32,33}}
-- 6、题目:输入某年某月某日,判断这一天是这一年的第几天?
分析:以3月5日为例,先把前两个月的加起来,然后再加上5天即本年第几天,特殊情况,闰年且输入月份大于3需考虑多加一天。可定义数组存储1-12月各月天数。
-- 7、使用二分法查找有序数组中元素。找到返回索引,不存在输出-1。使用递归实现
-- 8、数组A:1,7,9,11,13,15,17,19;数组b:2,4,6,8,10 两个数组合并为数组c,按升序排列。
-- 9、打印杨辉三角形(行数可以键盘录入)
五、答案
-- 1、
package day05;
class HomeWork01{
public static void main(String[] args) {
String words[] = new String[10];
Scanner sc = new Scanner(System.in);
int count=0;
//测试数据:Beijing Shanghai Shenzhen Guangzhou Xinjiang
//Qingdao Sichuan Chengdu Chongqing Heilongjiang
for(int i=1;i<=10;i++){ //循环输入数组的String类型的元素
System.out.println("请输入第"+i+"个单词");
words[i-1] = sc.next();
}
System.out.println("输入需要查询的单词:");
String find_word = sc.next();
for(int i=0;i<10;i++){
if (find_word.equals(words[i])) {
count++;
break;
}
}
if(count != 0){
System.out.println("Yes");
}else{
System.out.println("No");
}
}
}
-- 2、
package day05;
class HomeWork02{
public static void main(String[] args) {
int num1[] = new int[10];
Scanner sc = new Scanner(System.in);
int start_num=0;
int end_num=0;
for(int i=1;i<=num1.length;i++){
System.out.println("请输入第"+i+"个数字");
num1[i-1] = sc.nextInt();
}
for(int i=0;i<num1.length;i++){
System.out.print(num1[i]+" ");
}
System.out.println();//做换行符的作用
for(int i=0;i< num1.length/2;i++){//数组逆序
int tmp = num1[i];
num1[i] = num1[num1.length-1-i];
num1[num1.length-1-i] = tmp;
}
for(int i=0;i<num1.length;i++){//数组输出
System.out.print(num1[i]+" ");
}
}
}
-- 3、
package day05;
class HomeWork03{
public static void main(String[] args) {
int[] oldArr = new int[]{1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};
del_zore(oldArr);
}
public static void del_zore(int[] arr){//创建方法--除去数组中的元素0
int count = 0;
int index = 0;
for(int i=0;i<arr.length;i++){//查询旧数组中元素不为0的元素个数
if(arr[i]!=0){
count++;
}
}
System.out.println("非零元素个数:"+count);
int[] newArr = new int[count];//创建新数组,个数为旧数组的非0元素个数
for(int i=0;i<arr.length;i++){
if(arr[i]!=0){
newArr[index]=arr[i];
index++;
}
}
for(int i=0;i<count;i++){//输出数组
if(i==0){
System.out.print("["+newArr[i]+", ");
}else if(i==count-1){
System.out.println(newArr[i]+"]");
}else{
System.out.print(newArr[i]+", ");
}
}
}
}
-- 4、
package day05;
class HomeWork04 {
// 注释掉的这段,是冒泡排序方法的另一种形式读者可以参考
// public static int[] Bubble_sort(int[] arr) {//冒泡排序 升序排列 有数据类型的
// int tmp = 0;
// for (int i = 0; i < arr.length; i++) {//冒泡排序
// for (int j = i + 1; j < arr.length; j++) {
// if (arr[i] > arr[j]) {
// tmp = arr[i];
// arr[i] = arr[j];
// arr[j] = tmp;
// }
// }
// }
//
// for (int i = 0; i < arr.length; i++) {//输出冒泡排序
// System.out.print(arr[i] + " ");
// }
// return arr;
// }
public static void Bubble_sort(int[] arr) {//冒泡排序 升序排列 无数据类型的
int tmp = 0;
for (int i = 0; i < arr.length; i++) {//冒泡排序
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
for (int i = 0; i < arr.length; i++) {//输出冒泡排序
System.out.print(arr[i] + " ");
}
}
public static int dichotomy(int[] arr,int find_num) {//二分法,不存在,返回-1
int front = 0;
int end = arr.length-1;
int S = 0;
while(front<=end){ //二分法的编写方式
int mid = (front+end)/2;
if(arr[mid]==find_num){
return mid;
}else if(arr[mid]<find_num){
front = mid+1;
}else {
end = mid-1;
}
}
return -1;
}
public static void main(String[] args) {//主函数
Scanner sc = new Scanner(System.in);
System.out.println("输入数组的长度:");
int find_num = 0;
int arr1_num = sc.nextInt();
int[] arr1 = new int[arr1_num];
int[] arr2 = new int[arr1_num];
for (int i = 1; i <= arr1.length; i++) {
System.out.println("请输入数组的第" + i + "个元素");
arr1[i - 1] = sc.nextInt();
}
System.out.println("输入需要查询的数字:");
find_num = sc.nextInt();
Bubble_sort(arr1);
//
int output = dichotomy(arr1,find_num);
if(output == -1){
System.out.println("结果为:"+output+",该数组没有返回值");
}else{
System.out.println("结果为:"+output+",该数组有返回值");
}
}
}
-- 5、
package day05;
class HomeWork05 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum=0;
System.out.println("请输入二维数组的行数:");
int rows = scanner.nextInt();
System.out.println("请输入二维数组的列数:");
int cols = scanner.nextInt();
int[][] arr = new int[rows][cols];
System.out.println("请输入二维数组的元素:");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
arr[i][j] = scanner.nextInt();
}
}
for(int i = 0; i < arr.length; i++){
for(int j = 0; j < arr[i].length; j++){
sum += arr[i][j];
}
}
System.out.println("此二维数组的和为:"+sum);
}
}
-- 6、
package day05;
class HomeWork06{
public static void main(String[] args) {
int date_num=0;
Scanner sc = new Scanner(System.in);
System.out.println("输入需要查询的年份:");
int year = sc.nextInt();
System.out.println("输入需要查询的月份:");
int month = sc.nextInt();
System.out.println("输入需要查询的日期:");
int day = sc.nextInt();
int[] month_num = new int[]{31,28,31,30,31,30,31,31,30,31,30,31};
int[] run_month_num = new int[]{31,29,31,30,31,30,31,31,30,31,30,31};
if (month == 1){ //先判断月份,如果是1月则不需要调用数组
System.out.println("一共是"+day+"天");
}else{
if((year%4==0 & year%100!=0) | year%400==0){//再判断是否为闰年
for(int i=0;i<month-1;i++){
date_num += run_month_num[i];
System.out.println(date_num);
}
date_num += day;
System.out.println("一共是"+(date_num-1)+"天");
}else { //不是闰年,不是一月,直接算就行了
for(int i=0;i<month-1;i++){
date_num += month_num[i];
System.out.println(date_num);
}
date_num += day;
System.out.println("一共是"+(date_num-1)+"天");
}
}
}
}
-- 7、
package day05;
class Homework07{
public static int binarySearch(int[] arr,int front,int end,int find_num) {//二分法,不存在,返回-1
int S = 0;
while(front<=end){ //采用递归的方法运行二分法
int mid = (front+end)/2;
if(arr[mid]==find_num){
return mid;
}else if(arr[mid]<find_num){
return binarySearch(arr,mid+1,end,find_num);
}else {
return binarySearch(arr,front,mid-1,find_num);
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int output = 0;
System.out.println("请输入数组元素个数:");
int num = sc.nextInt();
int[] arr = new int[num];
for (int i = 1; i <= arr.length; i++) {
System.out.println("请输入数组的第" + i + "个元素");
arr[i - 1] = sc.nextInt();
}
System.out.println("请输入需要查寻的数:");
int find_num = sc.nextInt();
output=binarySearch(arr,0,num-1,find_num);
System.out.println("输出结果为:"+output);
}
}
-- 8、
package day05;
class HomeWork08{
public static void Bubble_sort(int[] arr) {//冒泡排序 升序排列 无数据类型的
int tmp = 0;
for (int i = 0; i < arr.length; i++) {//冒泡排序
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
for (int i = 0; i < arr.length; i++) {//输出冒泡排序
System.out.print(arr[i] + " ");
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数组元素个数:");
int num1 = sc.nextInt();
int[] arr1 = new int[num1];
for (int i = 1; i <= arr1.length; i++) {
System.out.println("请输入第一个数组的第" + i + "个元素");
arr1[i - 1] = sc.nextInt();
}
System.out.println("请输入第二个数组元素个数:");
int num2 = sc.nextInt();
int[] arr2 = new int[num2];
for (int i = 1; i <= arr2.length; i++) {
System.out.println("请输入第二个数组的第" + i + "个元素");
arr2[i - 1] = sc.nextInt();
}
int[] arr3 = new int[num1+num2];
for(int i=0;i<num1;i++){
arr3[i] = arr1[i];
}
int index = 0;
for(int i=num1;i<num1+num2;i++){
arr3[i] = arr2[index];
index++;
}
System.out.println("输出的结果为:");
Bubble_sort(arr3);
}
}
-- 9、打印杨辉三角形(行数可以键盘录入)
package day05;
class HomeWork09{//杨辉三角形
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入杨辉三角的行数:");
int num = sc.nextInt();
int[][] yang_sj = new int[num+2][num+2];
yang_sj[1][1] = 1;
if(num==1){
System.out.println("1");
}else{
System.out.println("1");
for(int i=2;i<=num;i++){
for(int j=1;j<=i;j++){
yang_sj[i][j]=yang_sj[i-1][j-1]+yang_sj[i-1][j];
System.out.print(yang_sj[i][j]+" ");
}
System.out.println();
}
}
}
}
如果你写了很久的题目,没有思路或写完题目略感颓废,请不要畏惧或放弃,作者写这些题目花费了六个半小时才写完。诸君的天赋一定是比作者好的,万不能轻言放弃。唯望诸君同我砥砺前行。万胜!!!