序列化流和反序列化流
public class demo02 {
public static void main(String[] args) throws IOException {
/*
序列化流:把基本流包装成高级流
构造方法:
public ObjectOutputStrteam(OutputStream out)
成员方法:把对象序列化(写出)到文件中去
public final void writeObject(Object obj)
*/
//1.创建学生对象
Student stu = new Student(23,"张三");
//2.对象操作输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08\\a.txt"));
//3.写出数据
oos.writeObject(stu);
//4.释放资源
oos.close();
}
}
运行结果:
public class demo01 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/*
需求:利用反序列化流/对象操作输入流,把文件中的对象读取到程序当中
构造方法:
public ObjectInputStream (InputStream out) 把基本流变成高级流
成员方法:
public Object readObject() 把序列化到本地文件中的对象,读取到程序当中
*/
//创建反序列化流的对象
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08\\a.txt"));
//2.读取数据
Student o=(Student)ois.readObject();
//打印对象
System.out.println(o);
//释放资源
ois.close();
}
}
运行结果:
打印流:只能写,不能读,只有输出流,是高级流
一般指的是:PrintStream,PrintWriter两个类
特点一:打印流只操作文件目的地,不操作数据源
特点二:特有的写出方法可以实现,数据原样写出,例如打印:97,文件中:97
特点三:特有的写出方法,可以实现自动刷新,自动换行
字节打印流:
public class demo03 {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
/* public PrintStream (OutputStream/File/String) 关联字节输出流/文件/文件路径
* public PrintStream(String filename,Charset charset) 指定字符编码
* public PrintStream (Stream filename,boolean autoFlush) 自动刷新
* Public PrintStream (OutputStream out,boolean autoFlush,String encoding) 指定字符编码且自动刷新
*
*
*
* 成员方法:
* public void write(int b) 常规方法:将指定的字节写出
* public void println() 特有方法:打印任意数据,自动刷新,自动换行
* public void print() 特有方法:打印任意数据,不换行
* public void print(String format) 特有方法:带占位符的打印的语句,不换行
* */
//1.创建字节打印流
PrintStream ps =new PrintStream(new FileOutputStream("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08\\b.txt"),true,"UTF-8");
//2.写出数据
ps.println(97);
//3.关闭资源
ps.close();
}
}
字符打印流:
public class demo04 {
public static void main(String[] args) throws IOException {
/*
字符打印流:
构造方法:
public PrintWriter(Write/File/String) 关联字节输出流/文件/文件路径
public PrintWriter(String filename,Charset charset) 指定字符编码
public PrintWriter(Write,boolean autoFlush) 自动刷新
public PrintWriter(Write out,boolean autoFlush,String encoding) 指定字符编码且自动刷新
成员方法:
public void write(int b) 常规方法:将指定的字节写出
public void println() 特有方法:打印任意数据,自动刷新,自动换行
public void print() 特有方法:打印任意数据,不换行
public void printf(String format,Object...args) 特有方法:带有占位符的打印语句
*/
//1.创建字符打印流的对象
PrintWriter pw=new PrintWriter(new FileWriter("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08\\d.txt"),true);
pw.println("Hello World");
pw.close();
}
}
压缩流:
public class demo05 {
public static void main(String[] args) throws IOException {
/*
压缩流:
把C:\Users\Administrator\IdeaProjects\day01\src\_2024_07_08\a.txt打包成一个压缩包
*/
//1.创建File对象表示要压缩的文件
File scr=new File("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08\\a.txt");
//2.创建File对象表示压缩包的位置
File dest=new File("C:\\Users\\Administrator\\IdeaProjects\\day01\\src\\_2024_07_08");
//3.调用方法来压缩
tozip(scr,dest);
}
public static void tozip(File scr,File dest) throws IOException {
//创建压缩流关联压缩包
ZipOutputStream zos=new ZipOutputStream( new FileOutputStream(new File(dest,"a.zip")));
//创建ZipEntry对象,表示压缩包里面的一个文件夹和文件
ZipEntry ze=new ZipEntry("a.txt");
//把ZipEntry对象放到压缩包当中
zos.putNextEntry(ze);
//把scr文件中的数据写到压缩包里面
FileInputStream fis=new FileInputStream(scr);
int b;
while((b=fis.read())!=-1){
zos.write(b);
}
zos.closeEntry();
zos.close();
}
}
=========================================================================
P1060 [NOIP2006 普及组] 开心的金明
#include <iostream>
#include<algorithm>
using namespace std;
const int N=30010;
int f[N];//表示不超过多少钱的时候可以得到的最大物品价格和重要度的乘积
int main(){
int n,m;
cin>>n>>m;int k,c;//n是总钱数,m是物品个数,k是物品价格,c是物品重要度
for(int i=0;i<m;i++){
cin>>k>>c;
int h=k*c;
for(int j=n;j>=k;j--){
f[j]=max(f[j],f[j-k]+h);
}
}
cout<<f[n]<<endl;
}
·使用一个数组来记录状态,例如dp[],其中dp[j们表示背包容量为j 时的最优解。
·使用物品的价值和重要度来动态更新这个状态数组,以求解最优解的问题。
总结来说,价值和重要度是描述物品属性的数组,而背包问题的解决方法则需要利用这些属性来动态规划求解最优解。
·f[i]数组用来存储背包容量为不同值时的最大价值。
·外层循环遍历每个物品,内层循环从背包容量m逆序更新f[i]数组,确保每个物品只能选一次,防止重复计算。 ·最后输出f[m]表示背包容量为m 时的最大价值。
P1359 租用游艇
#include <iostream>
#include<algorithm>
using namespace std;
int path[201][201];
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
path[i][j]=999999;
}
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
cin>>path[i][j];
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=0;j<=n;j++){
if(path[i][j]>path[i][k]+path[k][j]){
path[i][j]=path[i][k]+path[k][j];
}
}
}
}
cout<<path[1][n]<<endl;
}
算法步骤
1.初始化路径数组:首先将所有点对之间的路径长度初始化为一个足够大的数(999999,用于表示无穷大)。
2.读入直接路径:根据输入,更新已知的路径长度。
3.动态规划更新:使用三重循环,依次考虑是否通过中间点k可以缩短从点i 到点j 的路径长度。具体步骤是:
·对于每一个中间点k,遍历所有的点对(i,j)。
·如果当前已知的从 i到j的路径长度大于从 i经过k再到j的路径长度之和,则更新路径长度为更小的值。
4.最终输出结果:最终,path[1][n]就是从点1到点n的最短路径长度。
P3367 【模板】并查集
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N=2e5+10;
ll f[N];
int find(ll x){
if(f[x]==x)
return x;
else{
f[x]=find(f[x]);
}
return f[x];
}
int main(){
ll n,m;int x,y;
cin>>n>>m;int o;
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=1;i<=m;i++){
cin>>o;
cin>>x>>y;
if(o==2){
if(find(f[x])==find(f[y])){
cout<<"Y"<<endl;
}
else{
cout<<"N"<<endl;
}
}
else{
//if(find(f[x])!=find(f[y]))
f[find(y)]=find(x);
}
}
}
.并查集操作函数find :
·int find(1l x)函数用于查找元素×所在集合的根节点。
·使用路径压缩优化(Path Compression),在递归过程中将x 的父节点设为根节点,加速后续查询操作。