IO流:
存储和读取数字的解决方案。
分类:
四大家族:
字节输入流
字节输出流
字符输入流
字符输出流
纯文本文件:用windows自带记事本打开能读得懂的文件。
字节输出流:FileOutputStream
import java.io.FileOutputStream;
import java.io.IOException;
public class test {
public static void main(String[] args) throws IOException {
FileOutputStream fos=new FileOutputStream("src\\a.txt");
String str="abc";
byte[] arr=str.getBytes();
fos.write(arr);
String str2="\r\n";//换行符
byte[] byte1=str2.getBytes();
fos.write(byte1);
String str3="def";
byte[] byte2=str3.getBytes();
fos.write(byte2);
fos.close();//释放资源
}
}
运行操作结果:
示例:
字节输入流·:FileInputStream
循环读取:
可以自行打印b,也可以强转为char类型打印
如果b中存有字符a,自行打印就为97(ascll码表对应数字),强转就打印a。
文件拷贝:
字节流读取中文会出现乱码。
字符集:
计算机存储英文,一个字节就足以。
汉字以两个字节存储。
在UTF—8的编码规则下,英文占一个字节,中文3个字节(且第一个字节的首位是1)。
存在乱码原因:读取数据时未读完整个汉字。
编码和解码方法不统一。
Java中编码和解码的方法:
字符流:
FileReader:
idea默认是UTF—8
强转为char类型就行。
FileWriter:
二叉树的遍历:
已知两种遍历求另一种
// 情况1:中序+先序→后序
void inPreToPost(char in[], char pre[], int inStart, int inEnd, int* preIndex) {
if (inStart > inEnd) return;
// 当前子树的根是先序的第一个元素
char root = pre[(*preIndex)++];
// 在中序中找到根的位置
int inRoot = search(in, root, inEnd + 1);
// 递归处理左子树
inPreToPost(in, pre, inStart, inRoot - 1, preIndex);
// 递归处理右子树
inPreToPost(in, pre, inRoot + 1, inEnd, preIndex);
// 后序:最后输出根
printf("%c", root);
}
// 情况2:中序+后序→先序
void inPostToPre(char in[], char post[], int inStart, int inEnd, int* postIndex) {
if (inStart > inEnd) return;
// 当前子树的根是后序的最后一个元素
char root = post[(*postIndex)--];
// 在中序中找到根的位置
int inRoot = search(in, root, inEnd + 1);
// 先序:先输出根
printf("%c", root);
// 注意顺序:先右后左(因为postIndex是从后往前)
inPostToPre(in, post, inRoot + 1, inEnd, postIndex);
inPostToPre(in, post, inStart, inRoot - 1, postIndex);
}
// 情况3:先序+后序→中序(需满足每个节点有0或2个子节点)
int prePostToIn(char pre[], char post[], int preStart, int preEnd, int postStart, int postEnd) {
// 基本情况处理
if (preStart == preEnd) {
printf("%c", pre[preStart]);
return 1;
}
// 根节点
char root = pre[preStart];
// 左子树的根
char leftRoot = pre[preStart + 1];
// 在后序中找到左子树根的位置
int postLeftRoot = search(post, leftRoot, postEnd + 1);
// 计算左子树大小
int leftSize = postLeftRoot - postStart + 1;
// 递归处理左子树
int printed = prePostToIn(pre, post, preStart + 1, preStart + leftSize, postStart, postLeftRoot);
// 输出当前根(中序)
printf("%c", root);
// 递归处理右子树
printed += prePostToIn(pre, post, preStart + leftSize + 1, preEnd, postLeftRoot + 1, postEnd - 1);
return printed + 1;
}
洛谷p2440木材加工
解题思路:运用二分查找思路。最小的l是1,最大的l是木头中的最大长度,
进行二分查找,确认木头长度中的中间值是否满足条件,如果满足就尝试更大的l,如果不满足就降低l。最终得出答案。
AC代码:
#include<stdio.h>
#include<stdlib.h>
int cancut(int* lengths, int n, long long l, long long k) {
if (l == 0)return 0;
long long sum = 0;
for (int i = 0;i < n;i++) {
sum += lengths[i] / l;
if (sum >= k) {
return 1;
}
}
return sum >= k;
}
long long findmaxlength(int* lengths, int n, long long k) {
long long left = 1;
long long right = 0;
for (int i = 0;i < n;i++) {
if (lengths[i] > right) {
right = lengths[i];
}
}
long long max1 = 0;
while (left <= right) {
long long mid = left + (right - left) / 2;
if (cancut(lengths, n, mid, k)) {
max1 = mid;
left = mid + 1;
}
else
right = mid - 1;
}
return max1;
}
int main() {
int n;
long long k;
scanf("%d %lld", &n, &k);
int* lengths = (int*)malloc(n * sizeof(int));
for (int i = 0;i < n;i++) {
scanf("%d", &lengths[i]);
}
long long maxlength = findmaxlength(lengths, n, k);
printf("%lld\n", maxlength);
free(lengths);
return 0;
}