股票盈利问题(Java)——分治法(Maximum-subarray)

暴力法解此题:https://blog.csdn.net/qq_37486501/article/details/83000154

题目

在这里插入图片描述

  • 注意:
    1.本题采用txt文件读入,屏幕输出;
    如果需要屏幕读入屏幕输出,可以留言或者自己改代码~
    2.下面分int类型和double类型的数据读入,请选择适合自己的…

  • 分治法(Maximum-subarray)代码如下:
    要求(输入数据为int类型)

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
class Pro{
	private int i=0;//买入股票下标
	private int j=0;//卖出股票下标
	private int sum=0;//所加和
	private int k=0;
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public int getJ() {
		return j;
	}
	public void setJ(int j) {
		this.j = j;
	}
	public int getSum() {
		return sum;
	}
	public void setSum(int k) {
		this.sum =this.sum+k;
	}	
}

public class Lyx {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long startTime = System.currentTimeMillis();
		try {
		FileReader in = new FileReader("input.txt");
		BufferedReader inin=new BufferedReader(in);//读入文件
		 	try {
				 String str;   
				 int i=0;
				 int sum=Integer.parseInt(inin.readLine());
				 int[] datalist=new int[sum];
				while((str=inin.readLine())!=null)//每次读一行,注意双层括号
				 { 
				     datalist[i]=Integer.parseInt(str);
				     i++;
				 }
				int[] list=new int[sum];
				for(int m=1;m<sum;m++)
				{
					list[m]=datalist[m]-datalist[m-1];//list[ ]为股票( 后一天 - 前一天 )
				    //System.out.print(list[m]+" ");
				}		
				System.out.println("Maximum-subarray求解:");
	System.out.println("第"+(FindMaxSubarray(list,1,sum-1).getI()-1)+"日收盤買進第"+FindMaxSubarray(list,1,sum-1).getJ()+"日收盤賣出最高獲利為"+FindMaxSubarray(list,1,sum-1).getSum()+"元!");//求最大利润
		 	
		 	} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//计算时间
		long endTime = System.currentTimeMillis();
	    System.out.print("执行时间: "+(endTime-startTime)+" ms");	
	}
	public static Pro FindMaxSubarray (int[] data, int low,int high) { 
		int mid;
		Pro leftsum=new Pro();
		Pro rightsum=new Pro();
		Pro midsum=new Pro();
		if(high==low)
		   { 
			Pro pro1=new Pro();
			pro1.setI(low);
			pro1.setJ(high);
			pro1.setSum(data[high]);
			}
		else
			{	mid = (low+high)/2; 
				leftsum=FindMaxSubarray(data,low,mid);
				rightsum=FindMaxSubarray(data,mid+1,high);
				midsum=FindMaxCrossingSubarray(data,low,mid,high);
			}
				if((leftsum.getSum()>=rightsum.getSum())&&(leftsum.getSum()>=midsum.getSum()))
				{
					return leftsum;
				}
				else if((rightsum.getSum()>=leftsum.getSum())&&(rightsum.getSum()>=midsum.getSum()))
				{
					return rightsum;
				}
				else if((midsum.getSum()>=leftsum.getSum())&&(midsum.getSum()>=rightsum.getSum()))
				{
					return midsum;
				}			
		return null;  
	}
	public static Pro FindMaxCrossingSubarray (int[] data, int low,int mid,int high) {
		//以中间开始,向左边求sum1的max,向右边求sum2的max,两个max相加
		//左侧
		Pro pro1=new Pro();
		int leftsum=-1000;
		int sum1=0;//左侧各项相加的和
		int maxleftid=0;//左侧max时的i值
		for(int i=mid;i>=low;i--)
		{
			sum1=sum1+data[i];
			if(sum1>leftsum)
			{
				leftsum=sum1;
				maxleftid=i;	
			}
		}
		pro1.setSum(leftsum);
		pro1.setI(maxleftid);
		//右侧
		int rightsum=-1000;
		int sum2=0;//右侧各项相加的和
		int maxrightid=0;//右侧max时的i值
		for(int i=mid+1;i<=high;i++)
		{
			sum2=sum2+data[i];
			if(sum2>rightsum)
			{
				rightsum=sum2;
				maxrightid=i;	
			}
		}
		pro1.setSum(rightsum);
		pro1.setJ(maxrightid);
		return pro1;
	}
}
  • 分治法(Maximum-subarray)代码如下:
    要求(输入数据为double类型)
 import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
class Pro{
	private int i=0;//买入股票下标
	private int j=0;//卖出股票下标
	private double sum=0;//所加和
	private double k=0;
	public int getI() {
		return i;
	}
	public void setI(int i) {
		this.i = i;
	}
	public int getJ() {
		return j;
	}
	public void setJ(int j) {
		this.j = j;
	}
	public double getSum() {
		return sum;
	}
	public double setSum(double k) {
		return this.sum =this.sum+k;
	}	
}

public class Lyx {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long startTime = System.currentTimeMillis();
		try {
		FileReader in = new FileReader("input_2330.txt");
		BufferedReader inin=new BufferedReader(in);//读入文件
		 	try {
				 String str;   
				 int i=0;
				 int sum=Integer.parseInt(inin.readLine());
				 double[] datalist=new double[sum];
				while((str=inin.readLine())!=null)//每次读一行,注意双层括号
				 { 
				     datalist[i]=Double.parseDouble(str);
				     i++;
				 }
				double[] list=new double[sum];
				for(int m=1;m<sum;m++)
				{
					list[m]=datalist[m]-datalist[m-1];//list[ ]为股票( 后一天 - 前一天 )
				    //System.out.print(list[m]+" ");
				}			
				System.out.println("Maximum-subarray求解:");
	System.out.println("第"+(FindMaxSubarray(list,1,sum-1).getI()-1)+"日收盤買進第"+FindMaxSubarray(list,1,sum-1).getJ()+"日收盤賣出最高獲利為"+FindMaxSubarray(list,1,sum-1).getSum()+"元!");//求最大利润
		 	
		 	} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		//计算时间
		long endTime = System.currentTimeMillis();
	    System.out.print("执行时间: "+(endTime-startTime)+" ms");	
	}
	public static Pro FindMaxSubarray (double[] data, int low,int high) { 
		int mid;
		Pro leftsum=new Pro();
		Pro rightsum=new Pro();
		Pro midsum=new Pro();
		if(high==low)
		   { 
			Pro pro1=new Pro();
			pro1.setI(low);
			pro1.setJ(high);
			pro1.setSum(data[high]);
			}
		else
			{	mid = (low+high)/2; 
				leftsum=FindMaxSubarray(data,low,mid);
				rightsum=FindMaxSubarray(data,mid+1,high);
				midsum=FindMaxCrossingSubarray(data,low,mid,high);
			}
				if((leftsum.getSum()>=rightsum.getSum())&&(leftsum.getSum()>=midsum.getSum()))
				{
					return leftsum;
				}
				else if((rightsum.getSum()>=leftsum.getSum())&&(rightsum.getSum()>=midsum.getSum()))
				{
					return rightsum;
				}
				else if((midsum.getSum()>=leftsum.getSum())&&(midsum.getSum()>=rightsum.getSum()))
				{
					return midsum;
				}			
		return null;  
	}
	public static Pro FindMaxCrossingSubarray (double[] data, int low,int mid,int high) {
		//以中间开始,向左边求sum1的max,向右边求sum2的max,两个max相加
		//左侧
		Pro pro1=new Pro();
		double leftsum=-1000;
		double sum1=0;//左侧各项相加的和
		int maxleftid=0;//左侧max时的i值
		for(int i=mid;i>=low;i--)
		{
			sum1=sum1+data[i];
			if(sum1>leftsum)
			{
				leftsum=sum1;
				maxleftid=i;	
			}
		}
		pro1.setSum(leftsum);
		pro1.setI(maxleftid);
		//右侧
		double rightsum=-1000;
		double sum2=0;//右侧各项相加的和
		int maxrightid=0;//右侧max时的i值
		for(int i=mid+1;i<=high;i++)
		{
			sum2=sum2+data[i];
			if(sum2>rightsum)
			{
				rightsum=sum2;
				maxrightid=i;	
			}
		}
		pro1.setSum(rightsum);
		pro1.setJ(maxrightid);
		return pro1;
	}
}

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,关于使用Java语言基于分治法解决0-1背包问题,我可以给你一些思路。 首先,关于0-1背包问题,它是一个经典的动态规划问题。给定一定的背包容量和一堆不同的物品,每个物品有自己的重量和价值。我们需要选择一些物品放进背包中,使得它们的总重量不超过背包容量,而它们的总价值最大。 然后,分治法是一种递归的算法思想,它将问题分解成子问题,对每个子问题进行求解,然后将子问题的解合并得到原问题的解。 因此,使用分治法解决0-1背包问题,我们可以将原问题分成两个子问题:一个是不放当前物品,另一个是放当前物品。对于不放当前物品这个子问题,相当于求解在剩下的物品中选取一些物品放入背包中的问题,可以继续用相同的方法递归求解;对于放当前物品这个子问题,相当于在剩下的物品中选取一些物品放入背包中,但需要注意背包容量的变化。最终,我们将两个子问题的解进行合并,得到原问题的解。 具体实现时,可以使用Java编写一个递归函数,输入参数包括当前考虑的物品序号、背包剩余容量等。在函数内部,根据上述思路分别递归求解不放当前物品和放当前物品两个子问题,并将两个子问题的解合并得到当前问题的解。最终返回当前问题的解即可。 需要注意的是,分治法的时间复杂度可能比动态规划要高,因此需要根据具体情况选择合适的算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Laura_Wangzx

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

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

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

打赏作者

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

抵扣说明:

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

余额充值