VS C#开发求助:基于CheckedListBox按优先级计算所需点数卡片
Visual Studio C# 卡片数量计算功能实现步骤
核心逻辑说明
用贪心算法优先使用大点数卡片:先拿最大的可用卡片计算数量,剩余点数再用次大的卡片继续处理,直到点数耗尽或用完选中的卡片类型。
一、UI控件准备与命名
先给窗体上的控件设置好命名,方便代码操作:
- 输入总量的文本框:
txtTotalPoints - 可选卡片的复选列表框:
clbAvailableCards - 展示结果的标签:
lblCardsNeeded - 触发计算的按钮:
btnCalculate
二、初始化卡片数据
在窗体的Load事件中,给复选列表框添加卡片选项(按点数从大到小),用自定义类存储点数和显示文本:
// 自定义类,存储卡片的点数和显示名称 public class CardItem { public int Points { get; set; } public string DisplayName { get; set; } public CardItem(int points, string displayName) { Points = points; DisplayName = displayName; } } // 窗体加载时初始化卡片选项 private void Form1_Load(object sender, EventArgs e) { clbAvailableCards.Items.Add(new CardItem(64, "64-point")); clbAvailableCards.Items.Add(new CardItem(32, "32-point")); clbAvailableCards.Items.Add(new CardItem(16, "16-point")); clbAvailableCards.Items.Add(new CardItem(8, "8-point")); // 设置列表框显示的文本字段 clbAvailableCards.DisplayMember = "DisplayName"; }
三、编写计算逻辑(按钮点击事件)
在btnCalculate的Click事件中实现核心计算:
private void btnCalculate_Click(object sender, EventArgs e) { // 1. 验证输入的总量是否有效 if (!int.TryParse(txtTotalPoints.Text, out int totalPoints) || totalPoints <= 0) { lblCardsNeeded.Text = "请输入有效的正整数总量"; return; } // 2. 获取选中的卡片,并按点数从大到小排序 var selectedCards = clbAvailableCards.CheckedItems.Cast<CardItem>() .OrderByDescending(card => card.Points) .ToList(); if (selectedCards.Count == 0) { lblCardsNeeded.Text = "请至少选中一种卡片类型"; return; } // 3. 贪心算法计算各卡片需求数量 int remainingPoints = totalPoints; List<string> resultList = new List<string>(); foreach (var card in selectedCards) { if (remainingPoints <= 0) break; int cardCount = remainingPoints / card.Points; if (cardCount > 0) { resultList.Add($"{cardCount}x {card.DisplayName}"); remainingPoints -= cardCount * card.Points; } } // 4. 处理剩余无法覆盖的点数 if (remainingPoints > 0) { resultList.Add($"剩余 {remainingPoints} 点数无法用选中卡片覆盖"); } // 5. 展示结果 lblCardsNeeded.Text = string.Join(" 和 ", resultList); }
四、额外优化(可选)
限制输入框仅能输入数字
给txtTotalPoints添加KeyPress事件,防止输入非数字字符:
private void txtTotalPoints_KeyPress(object sender, KeyPressEventArgs e) { // 仅允许数字和退格键 if (!char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back) { e.Handled = true; } }
内容的提问来源于stack exchange,提问作者Robin Suicidal-Ocean Bolleurs
相关产品推荐
相关产品推荐

