You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Knuth洗牌算法实现Java随机单词生成及数组转换问题排查

问题说明

需要使用algs4库,基于Knuth洗牌算法从用户输入中选取随机单词。当前程序通过while循环将用户输入收集至ArrayList<String>,但转换为String[]时始终得到空数组——测试输入「hi ho」后输出空数组[],但ArrayList可正常显示[hi, ho]。同时希望了解两种实现路径:

  • 直接将输入转为String[]
  • 用Knuth算法对ArrayList进行洗牌

当前代码

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

public class RandomWord {

    public static void main(String[] args) throws IOException {
        StdOut.println("enter your words"); // StdIn.hasNextChar() = !StdIn.isEmpty()
        ArrayList<String> mylist = new ArrayList<String>();
        String store = new String();
        int count = 1;
        String[] arr = new String[mylist.size()];
        int k = 0;
        store = StdIn.readString();
        mylist.add(store);
        if (StdIn.hasNextChar() == false || mylist.contains(null)) {
            StdOut.println("you enter nothing");
        }
        else {
            while (count == mylist.size()) {
                while (StdIn.hasNextChar() == true) {
                    store = StdIn.readString();
                    mylist.add(store);
                    count++;
                    mylist.toArray(arr);
                    System.out.println(Arrays.toString(arr));
                }
            }
        }
    }
}

测试结果

enter your words

hi ho // 终端输入

[] // 输出结果


问题分析与解决方案

1. 数组为空的核心原因

你在初始化String[] arr时,mylist刚创建,size()为0,因此arr是长度为0的空数组。后续调用mylist.toArray(arr)时,由于数组长度不足,方法会返回一个新的、长度匹配的数组,但你没有接收这个返回值,原arr始终是空数组。

2. 修复数组转换问题

有两种可靠方式:

  • 等ArrayList收集完所有输入后,再创建匹配长度的数组:
    // 所有输入收集完成后执行
    String[] arr = mylist.toArray(new String[mylist.size()]);
    
  • 直接接收toArray()的返回值:
    arr = mylist.toArray(new String[0]);
    

3. 直接将输入转为String[]的最简方式

利用algs4库提供的StdIn.readAllStrings()方法,一行代码即可获取所有输入的单词数组(自动按空格分割):

String[] words = StdIn.readAllStrings();

这种方式比手动写循环更简洁、不易出错。

4. 对ArrayList实现Knuth洗牌算法

Knuth洗牌的核心逻辑是:遍历集合,对每个位置i,随机选取0 ≤ j ≤ i的位置交换元素。针对ArrayList的实现代码如下:

import edu.princeton.cs.algs4.StdRandom;

public static void knuthShuffle(ArrayList<String> list) {
    int n = list.size();
    for (int i = 0; i < n; i++) {
        // 生成0到i的随机索引
        int j = StdRandom.uniform(i + 1);
        // 交换i和j位置的元素
        String temp = list.get(i);
        list.set(i, list.get(j));
        list.set(j, temp);
    }
}

调用时直接传入你的mylist即可,洗牌后可直接选取任意位置的元素作为随机结果(比如取第一个元素)。


优化后的完整代码

import java.util.ArrayList;
import java.util.Arrays;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

public class RandomWord {

    // Knuth洗牌算法实现
    public static void knuthShuffle(ArrayList<String> list) {
        int n = list.size();
        for (int i = 0; i < n; i++) {
            int j = StdRandom.uniform(i + 1);
            String temp = list.get(i);
            list.set(i, list.get(j));
            list.set(j, temp);
        }
    }

    public static void main(String[] args) {
        StdOut.println("请输入单词:");
        
        // 方式1:用ArrayList收集输入
        ArrayList<String> mylist = new ArrayList<>();
        while (!StdIn.isEmpty()) {
            mylist.add(StdIn.readString());
        }

        if (mylist.isEmpty()) {
            StdOut.println("你没有输入任何内容");
            return;
        }

        // 转换为String[]并输出
        String[] arr = mylist.toArray(new String[mylist.size()]);
        StdOut.println("转换后的数组:" + Arrays.toString(arr));

        // 对ArrayList洗牌并随机选取单词
        knuthShuffle(mylist);
        StdOut.println("洗牌后的集合:" + mylist);
        StdOut.println("随机选取的单词:" + mylist.get(0));

        // ------------------------------
        // 方式2:直接读取为String[](注释掉方式1即可启用)
        // StdOut.println("请输入单词:");
        // String[] words = StdIn.readAllStrings();
        // if (words.length == 0) {
        //     StdOut.println("你没有输入任何内容");
        //     return;
        // }
        // // 对数组执行Knuth洗牌
        // for (int i = 0; i < words.length; i++) {
        //     int j = StdRandom.uniform(i + 1);
        //     String temp = words[i];
        //     words[i] = words[j];
        //     words[j] = temp;
        // }
        // StdOut.println("随机选取的单词:" + words[0]);
    }
}

内容的提问来源于stack exchange,提问作者DTJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:20:26