#求解一个java数组循环输出的问题:比如有一个数组A有4999个元素,创建一个B数组每次从A中取500个元素,一直循环输出B数组,如果A剩下的元素不足500个则从A的开始头重新取元素,如此循环往复。
#请问有什么简介的java算法或者函数吗?
该回答引用ChatGPT4与博主@晓码自在合作编写(代码和流程参考):
这是一个数组循环取元素的问题,可以使用以下Java代码实现:
java
int[] A = new int[4999]; //原数组
int[] B = new int[500]; //目标数组
int idx = 0; //A数组的当前索引
int len = 500; //每次取出的元素数量
while (true) {
int left = A.length - idx; //A数组剩余元素数量
if (left >= len) {
//A数组剩余元素足够,直接取len个
System.arraycopy(A, idx, B, 0, len);
idx += len; //A数组索引向后移动len
} else {
//A数组剩余元素不足len,先取剩余全部元素
System.arraycopy(A, idx, B, 0, left);
//然后从A数组头取len-left个元素
System.arraycopy(A, 0, B, left, len-left);
idx = len - left; //A数组索引归0
}
//使用B数组...
//处理逻辑
//循环继续
}
算法流程如下:
这是一个简单的数组循环取元素的算法实现,利用System.arraycopy可以高效复制数组元素。
你可以设置一个index记录A数组每次取得位置:
int[] A = new int[4999];
int[] B = new int[500];
boolean flag = false;
int index = 0;
while (true) {
for (int i = 0; i < B.length; i++) {
B[i] = A[index];
index++;
if (index >= A.length) {
index = 0;
flag = true;
}
}
for (int i = 0; i < B.length; i++) {
System.out.println(B[i]);
}
if (flag) {
index = 0;
flag = false;
}
}
本题总分:5 分
【问题描述】
在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。给定平面上 2 × 3 个整点 {(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z},即横坐标是 0 到 1 (包含 0 和 1) 之间的整数、纵坐标是 0 到 2 (包含 0 和 2) 之间的整数的点。这些点一共确定了 11 条不同的直线。给定平面上 20 × 21 个整点 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z},即横坐标是 0 到 19 (包含 0 和 19) 之间的整数、纵坐标是 0 到 20 (包含 0 和 20) 之间的整数的点。请问这些点一共确定了多少条不同的直线。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
【思路】
①每个点坐标(x,y),即有两个数据组成,可以使用String类型“x,y”形式存储。使用时split以“,”分开并且使用Integer的ParseInt。
②两点确定一直线使用两点式(y-y1)/(y2-y1)=(x-x1)/(x2-x1)表示直线,转换成标准式(y1-y2)x+(x2-x1)y-y1(x2-x1)+x1(y2-y1)=0。
③对系数和常数进行约分,即求三者最大公因数。
④取唯一,即对于求得结构相同的只算一次,可以考虑使用HashSet存储。
【Java代码】
import java.util.ArrayList;
import java.util.HashSet;
public class test {
public static void main(String[] args) {
//生成存储点
ArrayList<String> ps = new ArrayList<>();
for (int i = 0; i < 20; i++) {
for (int j = 0; j < 21; j++) {
//以"x,y"形式存储
ps.add(i + "," + j);
}
}
//取点求直线
HashSet<String> line = new HashSet<>();
//第一层循环取第一个点
for (int i = 0; i < ps.size(); i++) {
String p1 = ps.get(i);
int x1 = Integer.parseInt(p1.split(",")[0]);
int y1 = Integer.parseInt(p1.split(",")[1]);
//第二层循环取第二个点
for (int j = i+1; j < ps.size(); j++) {
String p2 = ps.get(j);
int x2 = Integer.parseInt(p2.split(",")[0]);
int y2 = Integer.parseInt(p2.split(",")[1]);
//根据(y1-y2)x+(x2-x1)y-y1(x2-x1)+x1(y2-y1)=0求系数及常数
int a = y1 - y2;
int b = x2 - x1;
int c = x1*(y2-y1)-y1*(x2-x1);
//求最大公因数约分
int m = gcd(gcd(a, b), c);
a /= m; b/= m; c/= m;
line.add(a + "," + b + "," + c);
}
}
System.out.println(line.size());
}
//求最大公因数
public static int gcd(int a, int b){
return b == 0 ? a : gcd(b, a%b);
}
}
【结果】
40257
可以使用滑动窗口算法来实现该需求。
具体步骤如下:
定义两个索引:left和right,用来记录当前取出的数据在数组A中的索引范围。初始时,left指向0,right指向499。
循环取500个数据,将这些数据存入数组B中,并循环输出数组B:
1) 遍历数组A,将left到right之间的数据存入数组B中。
2) 判断数组B是否已满,如果已满,则循环输出数组B。
3) 更新left和right的值,使它们指向下一个500个数据的范围。
4) 如果数组A中剩余元素不足500个,则重新从数组A的开头开始取元素,并将取到的数据添加到数组B中,直到数组A中的所有元素都被取完为止。
Java代码如下:
public static void main(String[] args) {
int[] A = new int[4999]; // 数组A,包含4999个元素
int[] B = new int[500]; // 数组B,每次取出500个数据存入其中
int left = 0, right = 499; // left和right记录当前取出的数据在数组A中的索引范围
for (int i = 0; i < 4999; i++) {
A[i] = i + 1;
}
while (left < 4999) {
// 遍历数组A,将left到right之间的数据存入数组B中
for (int i = left; i <= right && i < 4999; i++) {
B[i - left] = A[i];
}
// 判断数组B是否已满,如果已满,则循环输出数组B
if (right - left + 1 == 500) {
for (int i = 0; i < 500; i++) {
System.out.print(B[i] + " ");
}
System.out.println();
}
// 更新left和right的值,使它们指向下一个500个数据的范围
left += 500;
right = Math.min(right + 500, 4998);
}
// 循环输出数组B中剩余的数据
for (int i = left; i < 4999; i++) {
System.out.print(A[i] + " ");
}
}
上述代码中,滑动窗口的大小为500,每次取窗口中的数据存入数组B中,并判断数组B是否已满。如果已满,则循环输出数组B。
更新left和right的值时,先将left增加500,再将right增加500,但right不能超过数组A的最大索引值。
使用谷歌工具类 一行代码搞定
<!-- 谷歌并发包-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
List<String> list = new ArrayList<>(4999);
//判断一下 4999 是否 被 A 数组 每次取出的数量 整除 如果不是 就循环调用以下函数
Lists.partition(list,500).forEach(i-> System.out.println(JSON.toJSONString(i)));