Java基础练习(二)

1、实现二分法查找算法,要求返回目标值的下标

二分法是针对已经排序好的数组,将要查找的元素值,先与数组的中间值进行比较:如果等于中间值,则直接返回结果;如果小于中间值,则要查找的元素值必在前面一段的子数组中;如果大于中间值,则要查找的元素值必有后面一段的子数组中。
我实现该算法时的思路是,实现二分法查找算法首先要保证数组是顺序排列的,这样才能进行后续操作。所以我先用Array.sort方法保证数组是顺序排列的

for(int i=0;i<b.length;i++){
b[i]=Integer.parseInt(a[i]);
}
Arrays.sort(b);
System.out.println(“输入的数列排序后为:”);
System.out.println(java.util.Arrays.toString(b));

然后再通过循环来定位查找范围的界限。如果这样找完整个数列,都没有找到的话,就说明要找的值不再数列里。

代码实现

import java.util.Arrays;
import java.util.Scanner;
public class two {
    public static int fun(int key, int arr[]) {//传入两个参数,目标值和输入的数列
        int left = 0;//定义左边界
        int right = arr.length - 1;//定义有边界
        int mid = (left + right) / 2;//中间值
        if (key == arr[mid]) {
            return mid;
        } else {
            if (key < arr[mid]) {//说明目标值在前面一段
                mid = (left + mid) / 2;
            } else {
                if (key > arr[mid]) {//目标值在后面一段
                    right = mid;
                }
                return mid;
            }
            return -1;
        }
    }
    public static void main(String[] args) {
        System.out.println("请输入一个数列,数字用空格隔开");
        Scanner scanner=new Scanner(System.in);
        String str=scanner.nextLine();//读取一行数据
        System.out.println("请输入要查找的数字");
        Scanner m = new Scanner(System.in);
        int key = m.nextInt();//获得目标值
        String[] a=(str.split(" "));   //通过空格来分隔输入的数据
        int[] b=new int[a.length];//将数列传入到数组中
        for(int i=0;i<b.length;i++){
            b[i]=Integer.parseInt(a[i]);   //将String型转化成int型依次存放进数组b中
        }
        Arrays.sort(b);//将数组中的数据顺序排列
        System.out.println("输入的数列排序后为:");
        System.out.println(java.util.Arrays.toString(b));
        int i=fun(key,b);//调用上面写的方法
        if(i>=0)//判断目标值是否存在
        {
            System.out.println("所查找的数据排在第"+(i+1)+"位");
        }
        else {
            System.out.println("要查找的数不在输入数列范围");
        }
    }
}

2、求最大连续子数组

最大连续子数组: 给定一个整数数组,数组里可能有正数、负数和零。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和,我们要做的就是输出和最大的那个子数组,这就是最大连续子数组问题的本质。
在解决这个问题的时候,我想我们可以先定义一个数组,然后将输入的数组中每个连续子数组的和,放进我们创建的这个数组中,然后寻找这个数组中值最大的数,其下标就是输入数组最大连续子数组所对应的最后一个元素,最后输出这个下标之前的元素(包括这个下标对应的元素)。

首先,我们要确定存放每个连续子数组和的数组:、

int sum = 0;
int[] c = new int[b.length];
for (int i = 0; i < c.length;i++){
sum = sum + b[i];
c[i] = sum;
}

然后要得到对应的最长连续子数组最后一个元素的下标:

for (int i = 0;i<c.length;i++){
if (c[i]>f2){
f2 = c[i];
f1 = i;

这里的 f1 得到的就是所需要的下标。最后再输出结果就行了。

代码实现

import java.util.Scanner;
public class maxson {
    public static void main(String[] args){
        System.out.println("请输入数据,用空格隔开");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();//读取一行数据
       String[] a = (str.split( " "));//将数据存入数组a
       int[] b = new int[a.length];
       for (int i = 0;i<b.length;i++){
           b[i] = Integer.parseInt(a[i]);//把a数组里的数据转化为int型存进b数组里
       }
        int f1 = 0;//f1是用来获取下标
       int sum = 0;
       int[] c = new int[b.length];//用来存放每个连续子数组的和
       for (int i = 0; i < c.length;i++){
           sum = sum + b[i];
           c[i] = sum;
       }
       System.out.println("最长连续子数组为:");
           if (c.length>0){
               int f2 = c[0];
               for (int i = 0;i<c.length;i++){//查找最大值
                   if (c[i]>f2){
                       f2 = c[i];
                       f1 = i;//f1得到当前最大值的下标
                   }
           }
           for (int i = 0;i<=f1;i++){//输出最大了连续子数组
                 System.out.print(" "+b[i]);
           }
       }
    }
}

3、调换数组中两个元素的位置(不创建新的数组)

针对这个问题,我的思路是可以先获取想要交换的元素的值的下标,然后再把值互换就行了。

for (int i = 0;i<b.length; i++) {
if (f1 == b[i]) {
m = i;
}
}
for (int j = 0; j<b.length; j++) {
if (f2==b[j]){
n = j;
}
}

通过这样的方法就可以得到元素的下标。
然后再通过下面的方法转换数值:

f1 = f1 + f2;
f2 = f1 - f2;
f1 = f1 - f2;
b[m] = f1;
b[n] = f2;

最后输出转换后的数组就行了。

代码实现

import java.util.Scanner;
public class swap {
public static void main(String[] args) {
        System.out.println("请输入数据,用空格隔开");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();//读取一行数据
       String[] a = (str.split( " "));//将数据存入数组a
       int[] b = new int[a.length];
       for (int i = 0;i<b.length;i++){
           b[i] = Integer.parseInt(a[i]);//把a数组里的数据转化为int型存进b数组里
       }
        System.out.println("请输入想换位的数");
        int f1 = scanner.nextInt();//得到想换位的数
        System.out.println("请输入换位的目标数");
        int f2 = scanner.nextInt();//得到换位目标数
        int m = 0;//用来记录f1下标
        int n = 0;//用来记录f2下标
        fun(f1, f2, m, n, b);//传入参数,调用方法
        System.out.println("换位后数组为:");
        for (int i = 0; i <b.length; i++) {//输出换位后的数组
            System.out.print(" " + b[i]);
        }
    }
    public static void fun(int f1, int f2, int m, int n, int b[]) {
        for (int i = 0;i<b.length; i++) {//获得f1下标
            if (f1==b[i]) {
                m = i;
            }
        }
        for (int j = 0; j<b.length; j++) {//获得f2下标
           if (f2==b[j]){
               n = j;
           }
        }
        // 数值交换
        f1 = f1 + f2;
        f2 = f1 - f2;
        f1 = f1 - f2;
        b[m] = f1;
        b[n] = f2;
    }
}

4、逆置数组(不创建新数组)

其实这个问题和第三题的内容差不多,只不过这个问题所需要的是每个元素的下标,逆置数组就一般而言,可以看成中心对称,我采用的是if 循环语句,如果第一个元素下标是i,那么最后一项的下标就是array.length-i-1。依此类推,通过变量i的值改变对应的数据。

if (i<(b.length-i-1)){
b[i]=b[i]+b[b.length-i-1];
b[b.length-i-1]=b[i]-b[b.length-i-1];
b[i]=b[i]-b[b.length-i-1];
i++;
}

代码实现

    public class Inversion {
        public static void main(String[] args) {
        System.out.println("请输入数据,用空格隔开");
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine();//读取一行数据
       String[] a = (str.split( " "));//将数据存入数组a
       int[] b = new int[a.length];
       for (int i = 0;i<b.length;i++){
           b[i] = Integer.parseInt(a[i]);//把a数组里的数据转化为int型存进b数组里
       }
            int i=0;//i用来指示下标
            if (i<(b.length-i-1)){//如果坐标相等或者左边大于右边,则说明已经完成了
            //互换对应的值
                b[i]=b[i]+b[b.length-i-1];
                b[b.length-i-1]=b[i]-b[b.length-i-1];
                b[i]=b[i]-b[b.length-i-1];
                i++;
            }
            for (int j = 0; j <b.length; j++) {//输出逆置后的数组
                System.out.print(" " + b[j]);
            }
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值