如何使用LINQ实现扑克手牌字符串的多指定字符匹配筛选功能
实现思路
首先你需要先将用户输入的筛选文本解析为匹配规则集合,再针对每一条手牌验证是否满足所有规则:
- 先预定义合法点数、花色的字符集合,方便解析时区分点数、花色以及特定牌组合
- 解析输入时优先匹配「点数+花色」的特定牌规则,再匹配单字符的点数/花色规则,重复输入的字符对应要求满足的次数
- 验证手牌时逐个消耗匹配成功的规则和对应手牌,所有规则都被消耗完即为符合筛选条件
完整实现代码
首先定义辅助集合和两个工具方法:
// 预定义合法点数、花色集合,可根据你的实际表示规则调整 private static readonly HashSet<char> ValidRanks = new HashSet<char> {'2','3','4','5','6','7','8','9','T','J','Q','K','A'}; private static readonly HashSet<char> ValidSuits = new HashSet<char> {'s','h','d','c'}; // 解析用户输入为匹配规则列表 private List<string> ParseFilter(string filterInput) { var rules = new List<string>(); int index = 0; while (index < filterInput.Length) { // 优先判断是否是「点数+花色」的特定牌组合 if (index + 1 < filterInput.Length && ValidRanks.Contains(filterInput[index]) && ValidSuits.Contains(filterInput[index+1])) { rules.Add(filterInput.Substring(index, 2)); index += 2; } else { // 否则是单字符规则(点数或花色) rules.Add(filterInput[index].ToString()); index += 1; } } return rules; } // 验证单条手牌是否匹配所有规则 private bool IsHandMatch(string hand, List<string> rules) { // 先把手牌拆成单张牌的列表 var handCards = new List<string>(); for (int i = 0; i < hand.Length; i += 2) { if (i + 1 >= hand.Length) break; // 异常数据防护 handCards.Add(hand.Substring(i, 2)); } // 复制规则列表避免修改原数据 var remainingRules = new List<string>(rules); foreach (var rule in remainingRules.ToList()) { bool matched = false; foreach (var card in handCards.ToList()) { if (rule.Length == 2) { // 规则是特定牌,需要完全匹配 if (card == rule) { handCards.Remove(card); remainingRules.Remove(rule); matched = true; break; } } else { // 规则是单字符,匹配点数或花色 if (card[0] == rule[0] || card[1] == rule[0]) { handCards.Remove(card); remainingRules.Remove(rule); matched = true; break; } } } if (!matched) return false; // 有一条规则没匹配到直接返回不通过 } // 所有规则都匹配完成 return remainingRules.Count == 0; }
修改你原来的筛选逻辑即可:
// 先解析一次筛选规则,不用每次循环都解析 var filterRules = ParseFilter(txtHandFilter.Text.Trim()); for (int i = 0; i < allFilteredRows.Count; i++) { allFilteredRows[i] = new BindingList<CSVModel>(allRows[i] .Where(x => IsHandMatch(x.Combo, filterRules)) .ToList()); }
效果验证
- 输入
AK:会解析为两条规则["A","K"],匹配所有同时包含A和K的手牌 - 输入
sss:解析为三条规则["s","s","s"],匹配至少包含3张黑桃的手牌 - 输入
AKh:解析为["A","Kh"],匹配同时包含任意A和红桃K的手牌 - 输入
KA和AK解析结果一致,匹配效果相同
内容的提问来源于stack exchange,提问作者GasPanic
相关产品推荐
相关产品推荐

