C#如何实现从file.txt抽取不重复随机单词,抽完后提示对应信息
C# 随机无重复抽取单词实现方案
现有代码问题梳理
- 每次点击都重新读取文件,产生不必要的IO操作
- 没有对原始文件的单词做去重处理
- 没有维护已抽取单词的记录,无法判断是否重复展示
- 存在拼写错误
Lenght,正确写法为Length
实现方案
基础实现(适合单词量较小的场景)
提前读取文件做去重处理,维护已展示单词集合,每次抽取后判断是否重复,未重复则展示。
完整代码如下:
using System.Linq; using System.IO; // 全局变量定义 // 去重后的总单词库 private HashSet<string> _uniqueWords; // 已展示的单词集合 private HashSet<string> _shownWords = new HashSet<string>(); private Random _random = new Random(); // 文件路径统一配置,避免硬编码 private const string FilePath = @"C:\test\file.txt"; // 窗口加载/初始化阶段执行,仅读取一次文件 public void MainWindow_Loaded(object sender, RoutedEventArgs e) { // 读取文件内容,自动去重,同时过滤空行 var allLines = File.ReadAllLines(FilePath); _uniqueWords = new HashSet<string>(allLines.Where(line => !string.IsNullOrWhiteSpace(line))); } // 点击事件逻辑 public void randomClick(object sender, RoutedEventArgs e) { // 所有去重后的单词都已展示完成 if (_shownWords.Count >= _uniqueWords.Count) { _result.Text = "All words was shown"; return; } string pickedWord; // 循环抽取直到获取未展示过的单词 do { int randomIndex = _random.Next(_uniqueWords.Count); pickedWord = _uniqueWords.ElementAt(randomIndex); } while (_shownWords.Contains(pickedWord)); // 标记单词为已展示 _shownWords.Add(pickedWord); _result.Text = pickedWord; }
优化实现(适合单词量较大的场景)
初始化时直接将所有去重后的单词打乱顺序存入队列,每次点击直接出队获取下一个单词,无需循环判断重复,执行效率更高。
完整代码如下:
using System.Linq; using System.IO; // 全局变量定义 // 存储已打乱顺序的去重单词队列 private Queue<string> _shuffledWordsQueue; private const string FilePath = @"C:\test\file.txt"; // 窗口加载/初始化阶段执行 public void MainWindow_Loaded(object sender, RoutedEventArgs e) { // 读取文件并去重、过滤空行 var uniqueWords = new HashSet<string>(File.ReadAllLines(FilePath).Where(line => !string.IsNullOrWhiteSpace(line))); // 随机打乱单词顺序后存入队列 _shuffledWordsQueue = new Queue<string>(uniqueWords.OrderBy(_ => Guid.NewGuid())); } // 点击事件逻辑 public void randomClick(object sender, RoutedEventArgs e) { if (_shuffledWordsQueue.Count == 0) { _result.Text = "All words was shown"; return; } // 直接取出队列第一个元素即为未展示的随机单词 _result.Text = _shuffledWordsQueue.Dequeue(); }
内容的提问来源于stack exchange,提问作者JohnDown
相关产品推荐
相关产品推荐

