算法设计与分析实验题(实验四全为动态规划题 )

如果没有找到你想要的实验,可以在评论区评论,我有空会去写的(java版本)
如果本文章对你有所帮助 请记得点赞收藏一波 ( ̄︶ ̄)↗

第一次试验内容

1.Smith数问题

题目内容:若一个正整数的质因数分解式逐位相加之和等于其本身逐位相加之和,则称这个数为Smith数。如4937775=355*65837,而3+5+5+6+5+8+3+7=42,4+9+3+7+7+7+5=42,所以4937775是Smith数。 给定一个正整数N,求大于N的最小Smith数。
输入格式:若干个正整数,一行代表一个正整数N,以输入0表示结束
输出格式:按行输出大于正整数N的最小Smith数
输入样例:
4937774
200
0
输出样例:
4937775
202
代码位置:
注 :该题输入0 结束输入,输出结果

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class shuanfaseji1 {
    public  static void  main(String[] args) {
        Scanner in = new Scanner(System.in);
        int A = in.nextInt();
        List<Integer> list = new ArrayList<Integer>();
        while (A!=0){
            list.add(A);
             A = in.nextInt();
        }
        for(int str:list){
         System.out.println(Smith1(str));//如果不需要多行输入 main方法里面只要有本行即可,将str改成你需要的int类型数
        }
    }
    public static int Smith1(int A){
        if (Smith(A)){
            return A;
        }else {
            return Smith1(++A);
        }
    }
    public static int Smith3(int A){
        int e=0;
        while (A > 0) {
            e += A % 10;
            A/=10;
        }
        return e;
    }
    public static boolean Smith(int A){
        int B = 0, C = 0,D=A;
        int a = 2;
        while (D>1) {
            if (D % a == 0) {
                D/=a;
                B+=Smith3(a);
            }else{
                a++;
            }
        }
        C+=Smith3(A);
        if (B==C){
            return true;
        }
        return false;
    }
}

运行截图位置:
在这里插入图片描述

2.最接近数问题

题目内容:设计算法找出整数数组a[n](n<=50)中相差最小的两个元素(称为最接近数)的差。
输入格式:
第一行为数组大小n,第二行为n个数组元素,元素之间用空格分开
输出格式:
最接近数的差
输入样例:
5
65 38 26 75 40
输出样例:
2
代码位置:

import org.omg.CORBA.INTERNAL;
import java.util.Scanner;

public class zuixiaocha {
    public static void main(String[] args) {
        Scanner A=new Scanner(System.in);
        int a= A.nextInt();
        int[] B=new int[a];
        for (int i=0;i<a;i++){
            B[i]= A.nextInt();
        }
        B=paixu(B);
        System.out.println(cha(B));

    }
    public static int[] paixu(int[] A){
        int B=A.length;
        for (int i=0;i<B;i++){
            for (int j=i;j<B;j++){
                if(A[j]<=A[i]){
                    int C=A[i];
                    A[i]=A[j];
                    A[j]=C;
                }
            }
        }
        return A;
    }
    public static int cha(int[] A){
        int B=A.length;
        int J=A[1]-A[0];
        for (int i=1;i<B;i++){
            if(J>A[i]-A[i-1]){
                J=A[i]-A[i-1];
            }
        }
        return J;
    }
}

运行截图位置:
在这里插入图片描述

3.搬砖问题

有36个人36块砖头,男人可以搬4块,女人搬3块,两个小孩搬一块,要一次刚刚好搬完且人都过来
需要多少男人,多少女人,多少小孩?
运行代码:

public class banzhuan {
    public static void main(String[] args) {
    int wumen,men,boy;
    int zhuantou=36;
    for(wumen=0;wumen*4<=zhuantou;wumen++){
        for(men=0;(wumen*4+men*3)<=zhuantou;men++){
            for(boy=0;(wumen*4+men*3+0.5*boy)<=zhuantou;boy++){
                    if ((men+wumen+boy==36)&&(4*men+3*wumen+0.5*boy==zhuantou)){
                        System.out.println("男人有"+wumen+"个,女人有"+men+"个,小孩有"+boy+"个");
                    }
            }
        }
    }
    }
}

结果

男人有3,女人有3个,小孩有30

第一次实验内容

运动员举重问题

在这里插入图片描述

实验代码

import java.util.Scanner;
public class juzhong {
    public static void main(String[] args) {
        int t=8;//有几人参加
        Object[] q= shuru(t);//输入存储姓名 第几次 以及重量
        q=fenlie(q);//二路归并排序
        shucu(q,3*t);//输出结果
    }
    public static Object[] fenlie(Object[] q){
        if (q.length>3){
           int I=q.length/3;
            Object[] T= new Object[(I/2+I%2)*3];
            Object[] v= new Object[(I/2)*3];
           for (int i=0;i<(I/2+I%2)*3;i++){
               T[i]=q[i];
           }
            for (int i=(I/2+I%2)*3;i< q.length;i++){
                v[i-(I/2+I%2)*3]=q[i];
            }
            T=fenlie(T);
            v=fenlie(v);
            q=hebing(T,v);
        }
        return q;
    }
    public static Object[] shuru(int t){
        Object[] q=new Object[3*t];//存储姓名 第几次 以及重量
        Scanner in=new Scanner(System.in);
        for (int N = 0; N<3*t;){
            System.out.println("请确定输入人姓名");
            String J=in.nextLine();//输入姓名
            for (int i=0;i<3;i++,N++){
                System.out.println("请输入第"+(i+1)+"次举重重量");
                q[N]=shuru(J,i+1);
            }
        }
        return q;
    }
    private static void shucu(Object[] A,int J) {
        System.out.print("出场顺序号"+" ");
        System.out.print("姓名"+"  ");
        System.out.print("试举次数"+" ");
        System.out.println("试举重量"+" ");
        for (int i=0;i<J;i++){
            System.out.print("顺序号为"+(i+1)+" ");
            System.out.print(((Object[])A[i])[2]+"  ");
            System.out.print(((Object[])A[i])[1]+"    ");
            System.out.println(((Object[])A[i])[0]+" ");
        }
    }
    public static Object[] shuru(String A,int B ){
        Scanner in=new Scanner(System.in);
        Object[] C=new Object[3];//存储信息 2为姓名 1为次数 0为重量
        C[2]=A;
        C[1]=B;
        C[0]=in.nextInt();
        return C;
    }
    public static Object[] hebing(Object[] A,Object[] B){//顺序合并
        int a=A.length;
        int b=B.length;
        Object[]C=new Object[a+b];
        int i=0;//存放的位置
        while (a>0&&b>0){
            if ((int)(((Object[])A[A.length-a])[0])<=(int)(((Object[])B[B.length-b])[0])){
                C[i]=A[A.length-a];
                a--;
                i++;
            }else {
                C[i]=B[B.length-b];
                b--;
                i++;
            }
        }
        if (a==0){
            for(;b>0;b--){
                C[i]=B[B.length-b];
                i++; }
        }else {
            for(;a>0;a--){
                C[i]=A[A.length-a];
                i++;
            }
        }
        return C;
    }
}

运行结果
请添加图片描述

请添加图片描述
请添加图片描述
请添加图片描述

第二次实验内容

最大子数组


代码

public class szzf {
    public static void main(String[] args) {
        double[]  doublearr= {-0.3,-0.1,0.1,0.2,0.3,-0.1,0.1,0.3,0.4,-0.2};
        double [] B=szzf(doublearr);
        System.out.println("序号 误差 ");
        for(double i=B[1]; i<=B[2];i++) {
            System.out.println((int)i+"    "+doublearr[(int)i]);
        }
    }
    public static double[] szzf(double[] A){
        int left=0,right=A.length-1,sleft=0,sright= A.length-1;
        double max=qiuhe(A,0,A.length-1);
        while (sleft<sright){ 
            if (qiuhe(A,left,sleft)>qiuhe(A,sright,right)){
                if (qiuhe(A,sright,right)<0){
                    max-=qiuhe(A,sright,right);
                     sright-=1;
                     right=sright;
                }else {
                    sright-=1;
                }
            }else {
                if (qiuhe(A,sleft,left)<0){
					 max-=qiuhe(A,sleft,left);
                    sleft+=1;
                    left=sleft;
                }else {
                    sleft+=1;
                }
            }
        }
        double [] B={max, left,right};
    return B;
    }
    public static double qiuhe(double[] A,int B,int C){
        double n=0;
        for (;B<C+1;B++){
            n+=A[B];
        }
        return n;
    }
}

运行结果
请添加图片描述

注意
此处用的是双指针法 没有用分治法,自己写的不想改了
下面是我摘抄修改 的 分治法 交作业可以用这个

public class Subarray {
    //如果最大子数组横跨左右部分数组
    public static double[] FindMaxCrossingSubarray(double[] A, int low, int mid, int high) {
        double[] result = new double[3];
        //从中间点向左遍历,找出左半部分过中点的最大子数组
        double sum = 0;
        double i;
        for (i=mid;i>=low;i--) {
            sum = sum + A[(int)i];
            if (sum>result[2]) {
                result[2] = sum;
                result[0] = i;
            }
        }
        //从中间往右遍历,找出右半部分过中点的最大子数组
        sum = 0;
        result[2] = 0;
        for (i=mid;i<=high;i++) {
            sum = sum + A[(int)i];
            if (sum>result[2]) {
                result[2] = sum;
                result[1] = i;
            }
        }
        //将左右两个子数组组合
        result[2] = 0;
        for (i = result[0];i<=result[1];i++) {
            result[2] = result[2] + A[(int)i];
        }
        return result;
    }
    //将数组分成左右两个部分,依次计算左数组、右数组的最大子数组,再计算横跨左右部分的中间子数组,选择最大的输出
    public static double[] FindMaximumSubarray(double[] A, int low, int high) {
        double[] result = new double[3];
        double[] result_left = new double[3];
        double[]result_right = new double[3];
        double[] result_cross = new double[3];
        int mid = (int)(low+high)/2;
        //基本情况:数组中只有一个元素,则返回该数组
        if(low==high) {
            result[0]=low;
            result[1]=high;
            result[2]=A[low];
            return result;
        }
        //递归情况:数组中多于一个元素,依次计算三种情况下的最大子数组
        else {
            result_left = FindMaximumSubarray(A, low, mid);
            result_right = FindMaximumSubarray(A, mid+1, high);
            result_cross = FindMaxCrossingSubarray(A, low, mid, high);
            //比较三种情况的最大子数组,选择最大的输出
            if (result_left[2]>result_right[2] && result_left[2]>result_cross[2]) {
                return result_left;
            }
            else if (result_right[2]>result_left[2] && result_right[2]>result_cross[2]) {
                return result_right;
            }
            else {
                return result_cross;
            }
        }
    }
    public static void main(String[] args) {
        double[] result = new double[3];
        double[] A = {0.5, 0.1, -0.2, 0.2, 0.4, 0.3, -0.2, 0.1, 0.3, -0.3};
        result = FindMaximumSubarray(A, 0, A.length-1);
        System.out.println("序号 误差 ");
        for(double i=result[0]; i<=result[1];i++) {
            System.out.println(i+" "+A[(int)i]);
        }

    }
}

结果
在这里插入图片描述

第三次实验内容

背包问题

在这里插入图片描述
实验思路
思路一:用 数组去存储 每个物品的价值 重量 然后通过穷举法 将所有的购买可能性列出来 获取最优的一个(可以搞定可是和本文想用的有点差别)
思路二 用动态规划的思想去获取最大价值
实验代码

public class bbwt {
    static String[] name={" ","牙膏","啤酒","牛奶","面包", "香皂","台灯","面粉","大米","酱油","纸巾"};
    static int[] w = { 0 , 300 ,500 , 200 , 250,250,1000,4000,2000,800,200 };
    static double[] v = { 0 , 12 , 3 , 2.5 , 6,5,20,8,7,7,9 };
    static double[][] dp =new double[w.length][7000];
    static int bagV =dp[0].length-1;//动态规划表
    static int[] item=new int[dp.length];
    public static void main(String[] args) {
        findMax();
        findWhat(dp.length-1, dp[0].length-1);
        print();
    }

    public static void findMax() {					//动态规划
        for (int i = 1; i <= w.length-1; i++) {
            for (int j = 1; j <= bagV; j++) {
                if (j < w[i])
                    dp[i][j] = dp[i - 1][j];
                else
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
            }
        }
    }
    public static void findWhat(int i, int j) {				//最优解情况
        if (i > 0) {
            if (dp[i][j] == dp[i - 1][j]) {
                item[i] = 0;
                findWhat(i - 1, j);
            }
            else if (j - w[i] >= 0 && dp[i][j] == dp[i - 1][j - w[i]] + v[i]) {
                item[i] = 1;
                findWhat(i - 1, j - w[i]);
            }
        }
    }
    public static void print() {
        double max=0;
        System.out.println("商品编码 名称     重量     价格");
        for (int i = 1; i < dp.length; i++)		{
           double a=item[i];
           if(a==1){
               max+=a*v[i];
               System.out.println(i+"       " +  name[i]+"     "+w[i]+"    "+v[i]);
           }

        }
        System.out.println("总价格"+max);
    }
}

结果
在这里插入代码片

注:背包代码我是借鉴了一位前辈的代码修改的,
我自己写的一直有错 o(╥﹏╥)o 要不就是没用背包方法
下面是前辈的链接 不过这个前辈是用c语言写的
背包问题

方法二 博主写的

package algorithm;
public class shangping {
    String  name;
    int  weight;
    double value;
    public shangping(String name, int weight, double value) {
        this.name = name;
        this.weight = weight;
        this.value = value;
    }
}
package algorithm;
import algorithm.shangping;
public class zbbwt {
   static shangping[] supermarket={new shangping("牙膏",300,12),
            new shangping("啤酒",500,3),
            new shangping("牛奶",200,2.5),
            new shangping("面包",250,6),
            new shangping("香皂",250,5),
            new shangping("台灯",1000,20),
            new shangping("面粉",4000,8),
            new shangping("大米",2000,7),
            new shangping("酱油",800,7),
            new shangping("纸巾",200,9)};
    static double [][] Total_value=new double[supermarket.length+1][7000+1];//supermarket.length 为商品种类 7000为商品重量
    public static void main(String[] args) {
        for (int i = 1; i <= supermarket.length; i++) {
            for (int j = 1; j <= 7000; j++) {
                    Total_value[i][j]=max(i,j);
            }
        }
        print();
        System.out.println("总价值为:"+Total_value[Total_value.length-1][Total_value[0].length-1]);
    }

    private static void print() {
        int [] a = new int [supermarket.length];
        int N=Total_value.length-1;//存储当前商品
        int q=Total_value[0].length-1;//存储当前体重
        for (int i = supermarket.length; i >0 ; i--) {
                if (Total_value[N][q]-supermarket[i-1].value==Total_value[i-1][q-supermarket[i-1].weight]){
                    N=i-1;
                    q=q-supermarket[i-1].weight;
                    a[i-1]=1;
                }
        }
        System.out.println("商品名字"+"  是否购买");
        for (int i = 0; i < supermarket.length ; i++) {
            System.out.println(supermarket[i].name+"       "+(a[i]>0?"已购买":"未购买"));
        }
    }
    public static double max( int i,int j){
        double above=Total_value[i-1][j];
        double current=0;
        if (j>=supermarket[i-1].weight){
            current=Total_value[i-1][j-supermarket[i-1].weight]+supermarket[i-1].value;
        }
        return above>current?above:current;
    }
}

结果
在这里插入图片描述

第四次实验题

最长公共子序列

在这里插入图片描述

思路一:蛮举法 去列出所有子数组,从最长的到最短的一一对比获取相同的然后输出
实验代码:

import java.util.ArrayList;
public class zczc {
    public static void main(String[] args) {
        String i="ABCADEDBF";
        String j="ABDCEF";
        System.out.println("最长公共子序列为:"+zczc(i,j));
    }
    public static ArrayList<String> getSubset(String args){
        char[] set =args.toCharArray();
        int length=set.length;//元素个数
        int num=(2<<set.length-1)-1;//非空子集个数
        ArrayList<String> list=new ArrayList<String>();
        for(int i=1;i<=num;i++) {
            int now=i;  //暂存正在判断第i种可能
            String N ="";
            for(int j=0;j<=length-1;j++) {
                if((now&1)==1){  //为1时表示该元素已经存在
                    N+=set[j];
                }
                now=now>>1;   //依次判断下一位
            }
            list.add(N);
        }
        return list;
    }
    public static String zczc(String i,String j){
        if(i.length()<j.length()){//使i为最大的字符串j为最小的 方便下面使用
            String K=i;
            i=j;
            j=K;
        }
        int max=0;
        String maxstr="";
        Object[] iarr=getSubset(i).toArray();
        Object[] jarr=getSubset(j).toArray();
        for (int n=0;n<iarr.length-1;n++){
            for (int m=0;m<jarr.length-1;m++)
                if (iarr[n].equals(jarr[m])) {
                    if (iarr[n].toString().length() > max) {
                        max = iarr[n].toString().length();
                        maxstr = iarr[n].toString();
                    }
                }
        }
        return maxstr;
    }
}

结果

最长公共子序列为:ABCEF

(结果答案不唯一)
注:强烈表示不要用这个方法 ,复杂度太大了

思路二:动态规划

字符串最长公共子序列

public class dtzxl {
    public static void main(String[] args) {
        String i="ABCADEDBF";
        String j="ABDCEF";
        dtzxl(i,j);
    }
    public static void dtzxl(String i,String j){
        int[][] max=new int[i.length()+1][j.length()+1];
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (i.charAt(n - 1) == j.charAt(m - 1)) {
                    max[n][m] = max[n - 1][m - 1] + 1;//如果相同值为左上角加一
                } else {
                    max[n][m] = Math.max(max[n][m - 1], max[n - 1][m]);//不同则等于上方与左边中的最大值
                }
            }
        }
        System.out.print("最长子串为:");
        for (int m=1;m<=j.length();m++) {
            if (max[i.length()][m]!=max[i.length()][m-1]){
                System.out.print(j.charAt(m-1));
            }
        }

        System.out.println();
        System.out.println("长度为:"+max[i.length()][j.length()]);
    }
}

结果
在这里插入图片描述

文件对比相似度

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class dtzxl {
    public static void main(String[] args) {
        String i=wenjianhuoqu("C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt1.txt");//填写文件地址
        String j=wenjianhuoqu("C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt2.txt");//填写文件地址
        dtzxl(i,j);
    }
    public static String wenjianhuoqu(String txt){
        int num=0;
        char[] buf=new char[1024];//1024为存储的最大字数 可修改
        //打开文件
        FileReader fr = null;
        try {
            fr = new FileReader(txt);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        //取出字符存到buf数组中
        while(true) {
            try {
                if (!((num=fr.read(buf))!=-1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String str="";
        for (char i:buf){
                str+=i;
        }
        str=str.trim();
        return str;
    }
    public static void dtzxl(String i,String j){
        int[][] max=new int[i.length()+1][j.length()+1];
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (i.charAt(n - 1) == j.charAt(m - 1)) {
                    max[n][m] = max[n - 1][m - 1] + 1;
                } else {
                    max[n][m] = Math.max(max[n][m - 1], max[n - 1][m]);
                }
            }
        }
       // System.out.println("相同字段长度为:"+max[i.length()][j.length()]);
        System.out.println("相似度为:"+max[i.length()][j.length()]/(double)(i.length()>j.length()?j.length():i.length()));
    }
}

txt1内容
在这里插入图片描述
txt2内容
在这里插入图片描述
结果
在这里插入图片描述

最长公共子串

在这里插入图片描述
实验思路
先写出获取最长公共子串的方法再去写文件的近似度
实验代码
获取最长公共子串
本质上还是动态规划 只是将输入与获取方法改了一下

public class wjxsd {
    public static void main(String[] args) {
        String i="abcdeE";
        String j="axbccdeE";
        wjxsd(i,j);
    }

    public static void wjxsd(String i,String j){
        int[][] max=new int[i.length()+1][j.length()+1];
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (i.charAt(n - 1) == j.charAt(m - 1)) {
                    max[n][m] = max[n - 1][m - 1] + 1;
                }
            }
        }
        int maxx=0;
        int index=0;
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (max[n][m]>maxx) {
                    maxx=max[n][m];
                    index=n;
                }
            }
        }
         System.out.println("相同字段长度为:"+maxx);
        System.out.println("相同字段长度为:"+i. substring(index-maxx,index));
    }
}

实验结果

相同字段长度为:4
相同字段长度为:cdeE

文件近视度
txt1内容

某张在学习12345678
某张在学习12345678某张在学习12345678
某张在学习12345678

txt2内容

SDSD12345678
SDSD12345678
SDSD12345678某张在学习12345678某张在学习12345678
阿巴阿巴
import java.io.*;
import java.util.Scanner;
public class wjxsd {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        System.out.println("请输入第一个文件地址");
        String i=wenjianhuoqu(in.next());//填写文件地址如C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt1.txt
        System.out.println("请输入第二个文件地址");
        String j=wenjianhuoqu(in.next());//填写文件地址诶C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt2.txt
//        System.out.println(i);
//        System.out.println(j);
        wjxsd(i,j);
    }
    public static String wenjianhuoqu(String txt){
        int num=0;
        String buf="";
        //打开文件
        String l = null;
        try {
            BufferedReader r= new BufferedReader(new InputStreamReader(new FileInputStream(txt), "Utf-8"));
            while ((l=r.readLine())!=null){
                buf+=l+"\n";
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buf;
    }
    public static void wjxsd(String i,String j){
        int[][] max=new int[i.length()+1][j.length()+1];
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (i.charAt(n - 1) == j.charAt(m - 1)) {
                    max[n][m] = max[n - 1][m - 1] + 1;
                }
            }
        }
        int maxx=0;
        int index=0;
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                if (max[n][m]>maxx) {
                    maxx=max[n][m];
                    index=n;
                }
            }
        }
       if(i.charAt(index-1)=='\n'){//去除尾部的换行键
            maxx--;
            index--;
        }
        System.out.println("相同字段长度为:"+maxx);
        System.out.println("相同字段为:"+i. substring(index-maxx,index));
        System.out.println( "相似度为:"+(int)(maxx/(double)(i.length()>j.length()?j.length():i.length())*100)+"%");
    }
}

实验结果

请输入第一个文件地址
C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt1.txt
请输入第二个文件地址
C:\\Users\\HX\\Desktop\\xuexi\\untitled\\src\\txt2.txt
相同字段长度为:26
相同字段为:某张在学习12345678某张在学习12345678
相似度为:46%

文件近似度是获取最长公共子串的进阶题 按个人需要自取即可
如果是摘抄交作业什么的请记得修改文件内容 自行运行一次

编辑距离问题

在这里插入图片描述
实验思路
运用了动态规划的思想去对两个字符串进行判断 对比,然后得出最有效的方法步骤。
实验代码

import java.util.Scanner;
public class bjjlwt {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        System.out.println("请输入字符");
        String i=in.nextLine();
        System.out.println("请输入需要修改成的字符");
        String j=in.nextLine();
        bjjlwt(i,j);
    }
    public static void bjjlwt(String i,String j){
        int[][] min=new int[i.length()+1][j.length()+1];
        String[][] czbz=new String[i.length()+1][j.length()+1];
        for (int n=0;n<=i.length();n++) {
            min[n][0]=n;
            czbz[n][0]="U";
        }
        for (int m = 0; m <= j.length(); m++) {
            min[0][m]=m;
            czbz[0][m]="L";
        }
        for (int n=1;n<=i.length();n++) {
            for (int m = 1; m <= j.length(); m++) {
                int Q= Math.min(Math.min(min[n][m - 1], min[n - 1][m]),min[n-1][m - 1]);
                if (i.charAt(n - 1) == j.charAt(m - 1)) {
                    min[n][m] = min[n - 1][m - 1];//如果相同 值等于左上角
                    czbz[n][m]="LU";
                } else {
                    if (min[n-1][m-1]==Q){
                        czbz[n][m]="LU";
                    }else if (min[n][m - 1]==Q){
                        czbz[n][m]="L";
                    }else {
                        czbz[n][m]="U";
                    }
                    min[n][m] =  Q+1;//不同则等于上方与左边中的最小值+1
                }
            }
        }
        for (int n=0;n<=i.length();n++) {
            for (int m = 0; m <= j.length(); m++) {
                System.out.print(min[n][m]);
            }
            System.out.println();
        }
//        for (int n=0;n<=i.length();n++) {
//            for (int m = 0; m <= j.length(); m++) {
//                System.out.print(czbz[n][m]+"  ");
//            }
//            System.out.println();
//        }
        int n=i.length();
        int m=j.length();
        System.out.println("序列号    操作步骤      结果");
        int xulei=1;
        while (m!=0||n!=0){
            if (czbz[n][m].equals("LU")){
                if(i.charAt(n-1)==j.charAt(m-1)){
//                    System.out.println(xulei+++"    "+"无操作");
                }else {
                    System.out.printf( "%2s%8s%s%s%s",xulei++,"将",i.charAt(n-1),"替换为",j.charAt(m-1));
                    i=i.substring(0,n-1)+j.charAt(m-1)+i.substring(n);
                    System.out.println("    "+i);
                }
                n--;m--;
            }else if (czbz[n][m].equals("U")){
                System.out.printf( "%2s%10s%s   ",xulei++,"刪除",i.charAt(n-1));
                i=i.substring(0,n-1)+i.substring(n);
                System.out.println("    "+i);
                n--;
            }else {
                System.out.printf( "%2s%10s%s    ",xulei++,"插入",j.charAt(m-1));
                i=i.substring(0,n)+j.charAt(m-1)+i.substring(n);
                System.out.println("    "+i);
                m--;
            }
        }
        System.out.println("最小编辑距离为:"+--xulei);
    }
}

运行结果
在这里插入图片描述

钢条切割问题

在这里插入图片描述
实验思路

获取 前缀组合

实验代码

package algorithm;

import java.util.ArrayList;
public class gangtiaoqiege {
    static int [] pl={0,1,5,8,9,10,17,17,20,24,24};
    static int [] j=new int[pl.length-1];
    static int [] c=new int[pl.length];
    public static void main(String[] args) {
        outprint();
        fanhui();
    }
    public static void fanhui(){
        ArrayList<Integer> list=new ArrayList<Integer>();
        for (int i = 0; i < j.length; i++) {
            if (j[i]==cmax()){
                list.add(i+1);
            }
        }
        int N= j.length;
        int len=list.size()-1;
        System.out.print("方案为:");
        while (N>0){
            if (N>=list.get(len)){
                System.out.print(list.get(len)+" ");
                N-=list.get(len);
            }else {
                len--;
            }
        }
    }
    private static void outprint() {
        huoqu();
        System.out.println("最大价值为:"+cmax());
    }
    public static  int cmax(){
        return c[c.length-1];
    }
    public static void huoqu(){
        for (int i = 1; i < c.length ; i++) {
            c[i]=max(i);
        }
    }
    private static int max(int i) {
        for (int k = 1; k <=i; k++) {
            j[k-1]=c[i-k]+pl[k];
        }
        int max=0;
        for (int k = 0; k <i ; k++) {
            if (max<j[k]){
                max=j[k];
            }
        }
        return max;
    }
}

实验结果
在这里插入图片描述

活动安排问题

在这里插入图片描述
实验代码

package algorithm;

import java.util.Arrays;
import java.util.Comparator;

public class hdsjap {
    public static activity[] activitys = null;
    public static int[] BeforeEnd;//之前结束活动
    public static int[] MaxRevenue;//最大价值
    public static int[] ischoose;//是否选择

    public static void main(String[] args) {
        activitys = new activity[]{
                new activity("A1", 1, 4, 1),
                new activity("A2", 3, 5, 6),
                new activity("A3", 0, 6, 4),
                new activity("A4", 4, 7, 7),
                new activity("A5", 3, 9, 3),
                new activity("A6", 5, 9, 12),
                new activity("A7", 6, 10, 2),
                new activity("A8", 8, 11, 9),
                new activity("A9", 8, 12, 11),
                new activity("A10", 2, 14, 8)
        };
        //给数组根据结束时间排序
        Arrays.sort(activitys, new Comparator<activity>() {
            @Override
            public int compare(activity o1, activity o2) {
                return o1.EngTime - o2.EngTime;
            }
        });
        //获取每个 活动开始之前的可以进行的最后一个活动(注意 按个输入不是角标)
        BeforeEnd = new int[activitys.length];
        for (int i = 1; i < activitys.length; i++) {
            for (int j = i - 1; j >= 0; j--) {
                if (activitys[i].BeginTime >= activitys[j].EngTime) {
                    BeforeEnd[i] = j + 1;
                    break;
                }
            }
        }
//      System.out.println(Arrays.toString(BeforeEnd));//测试
        MaxRevenue = new int[activitys.length + 1];//初始化
        ischoose = new int[activitys.length];
        for (int i = 0; i < activitys.length; i++) {
            MaxRevenue[i + 1] = MaxRevenue[i] > MaxRevenue[BeforeEnd[i]] + activitys[i].revenue ? MaxRevenue[i] : MaxRevenue[BeforeEnd[i]] + activitys[i].revenue;
            if (MaxRevenue[i + 1] > MaxRevenue[i]) {
                ischoose[i] = 1;
            }
        }
//      System.out.println(Arrays.toString(MaxRevenue));//测试
//      System.out.println(Arrays.toString(ischoose));//测试
        for (int i = activitys.length - 1; i > 0; i--) {
            if (ischoose[i] == 1) {
                System.out.println("活动编号   收益");
                while (i >= 0) {
                    System.out.println(activitys[i].name + "        " + activitys[i].revenue);
                    i = BeforeEnd[i] - 1;
                }
                System.out.println("总收益为: " + MaxRevenue[MaxRevenue.length - 1]);
                break;
            }
        }
    }
}

class activity {
    String name;
    int BeginTime;
    int EngTime;
    int revenue;

    public activity(String name, int beginTime, int engTime, int revenue) {
        this.name = name;
        BeginTime = beginTime;
        EngTime = engTime;
        this.revenue = revenue;
    }

}

实验结果
在这里插入图片描述

有问题或者需要更新请私聊我 该文章会持续更新 请注意收藏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zzsaixuexi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值