关于#算法#的问题:#请问有什么简介的java算法或者函数吗

#求解一个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数组...
    //处理逻辑
    
    //循环继续
}

算法流程如下:

  1. 定义原数组A和目标数组B,以及索引idx和每次取元素数量len
  2. 计算A数组剩余元素数量left
  3. 如果left>=len,直接从A中idx索引开始取len个元素到B数组
  4. 如果left<len,先取A中的所有剩余元素left个到B数组,然后从A头取len-left个元素到B数组
  5. 处理B数组,继续循环
  6. 每次循环,将A的索引idx向后移动len,代表已经取出的元素
  7. 这样每次从A中取len个元素到B数组,当A剩余元素不足len时循环取,实现了你要的效果。

这是一个简单的数组循环取元素的算法实现,利用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;
    }
}


  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/1097732
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:明明生成了N个1到500之间的随机整数。请你删去其中重复的数字,即相同的数字只保留一个,把其余相同的数去掉,然后再把这些数从小到大排序,按照排好的顺序输出。(java)
  • 除此之外, 这篇博客: 第十二届蓝桥杯A组省赛填空题Java思路及代码合集(相乘直线货物摆放路径回路计数)中的 试题 B: 直线 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 本题总分: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


  • 以下回答由chatgpt基于相关博客总结生成:

    可以使用滑动窗口算法来实现该需求。

    具体步骤如下:

    1. 定义两个索引:left和right,用来记录当前取出的数据在数组A中的索引范围。初始时,left指向0,right指向499。

    2. 循环取500个数据,将这些数据存入数组B中,并循环输出数组B:

    1) 遍历数组A,将left到right之间的数据存入数组B中。

    2) 判断数组B是否已满,如果已满,则循环输出数组B。

    3) 更新left和right的值,使它们指向下一个500个数据的范围。

    4) 如果数组A中剩余元素不足500个,则重新从数组A的开头开始取元素,并将取到的数据添加到数组B中,直到数组A中的所有元素都被取完为止。

    1. 循环输出数组B中剩余的数据。

    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)));