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]);
}
}
}