知识点:排序 字持串 队列 循环 map
题目描述:9月份开学第一天,小学某班级进行班长选举活动,班级共有N个学生,每个学生最多可投3票(对同一个人只能投一票),也可以弃权不投票,大家投票时写上对应学生的名字(假设学生不存在重名,考虑到部分少数民族名字带点分隔,且整体较长,同学在投票时为了方便,允许同学写上全称,
也可以只写其中的部分连续段,比如班级里只有2个少数民族名称带点的同学,A同学叫买买提·艾尔肯·巴图尔,B同学叫买买提·艾尔肯.库尔班,那要给A同学投票,可以写 买买提.艾尔肯.巴图尔或者 艾尔肯.巴图尔或者巴图尔,但是不能写买买、买买提·艾、肯.库尔班、肯.库这种某名字段未写全的情况),学生可以把票投给自己。得票最多的同学当选班长,如果票数相同,则按名字做字符串排序,排序靠前的当选班长。
如果选票上写的名字不合理(要求投票写的名字必需是连续的,少数民族可以是连续的若干段,但要求每段名称要写全,选票上的名字需要能唯一匹配某个人),则认为是无效票,直接忽略。如果出现原始输入总选票数超过3倍班级总人数、某位同学的得票数超过班级总人数、没有一个同学被选中这些情况,则认为选举无效,返回固定字符串"Invalid election"
现在投票环节已完成,进入唱票环节,请你完善代码根据投票数据,给出当选班长对应的完整名称。 方法共2个参数,第一个参数是全班同学的名称集合,第二个参数是选票数据集合。考虑到部分语言对中文处理不太友好,名称输入统一为普通的ASCII字符,选票中少数民族名称中的连接符()改用英文横杠连接符(-)。
------------------------
示例一:
输入:['Zhangsan'. 'Lisi', 'Wangwu'].I'Zhangsan',"Lisi",'Zhangsan']
输出:'Zhangsan'
说明:Zhangsan得2张选票,Lisi只得1张选票,Zhangsan票数更高,因此Zhangsan当选班长。
示例二:
输入:['Zhangsanfeng'.'Zhangsande'].['Zhangsan'. "Zhangsande','Zhangsan']
输出:"Zhangsande"
虽然Zhangsan有2张选票,由于不属于班级成员,对应选票无效,因此获得1张选票的Zhangsande当选班长。
示例三:
输入:["maimaiti-aierken-batuer', 'maimaiti-aierken-kuerban'],/'batuer". "aierken-batuer", "maimaiti'.
aierken-kuerban']
输出:'maimaiti-aierken-batuer
说明:"batuer"和"aierken-batuer"都能唯一匹配"maimaiti-aierken-batuer",因此"maimaiti-aierken-batuer"获得2票,"maimaiti"因为有多个名字都匹配,认为无效票。"maimaiti-aierken-kuerban"能唯一匹配,获得1票,所以得票更多的"maimaiti-aierken-batuer"当选班长。
解决方案
根据题目要求,需要实现一个函数来处理班长选举的唱票环节。核心逻辑包括:验证选举有效性、处理选票匹配、计票统计及结果判定。以下是使用不同编程语言的实现,均遵循题目要求的匹配规则和边界条件。
关键逻辑说明:
- 有效性检查:
- 总选票数超过班级人数的3倍,直接返回无效选举。
- 任何学生得票数超过班级人数,返回无效选举。
- 所有选票均无效时,返回无效选举。
- 名字匹配规则:
- 将学生姓名和选票按
-分割成段。 - 选票必须匹配某学生姓名的连续完整段序列(不能部分段)。
- 必须唯一匹配,否则视为无效票。
- 将学生姓名和选票按
- 计票与结果:
- 统计有效票数。
- 得票最高者当选;若平票,按字符串字典序取最小者。
1. Python 实现
def is_continuous_subsequence(vote_tokens, student_tokens): n = len(vote_tokens) m = len(student_tokens) if n > m: return False for i in range(m - n + 1): if student_tokens[i:i+n] == vote_tokens: return True return False def elect_monitor(students, votes): n = len(students) if len(votes) > 3 * n: return "Invalid election" student_tokens = {s: s.split('-') for s in students} vote_count = {s: 0 for s in students} for vote in votes: vote_tokens = vote.split('-') if not vote_tokens: continue matches = [] for s, tokens in student_tokens.items(): if is_continuous_subsequence(vote_tokens, tokens): matches.append(s) if len(matches) == 1: vote_count[matches[0]] += 1 max_votes = max(vote_count.values()) if vote_count else 0 if max_votes == 0: return "Invalid election" for s in students: if vote_count[s] > n: return "Invalid election" candidates = [s for s in students if vote_count[s] == max_votes] candidates.sort() return candidates[0]2. Java 实现
import java.util.*; public class Election { public static String electMonitor(String[] students, String[] votes) { int n = students.length; if (votes.length > 3 * n) { return "Invalid election"; } Map<String, String[]> studentTokens = new HashMap<>(); Map<String, Integer> voteCount = new HashMap<>(); for (String s : students) { studentTokens.put(s, s.split("-")); voteCount.put(s, 0); } for (String vote : votes) { String[] voteTokens = vote.split("-"); if (voteTokens.length == 0) continue; List<String> matches = new ArrayList<>(); for (String s : students) { String[] tokens = studentTokens.get(s); if (isContinuousSubsequence(voteTokens, tokens)) { matches.add(s); } } if (matches.size() == 1) { voteCount.put(matches.get(0), voteCount.get(matches.get(0)) + 1); } } int maxVotes = 0; for (int count : voteCount.values()) { if (count > maxVotes) maxVotes = count; } if (maxVotes == 0) return "Invalid election"; for (String s : students) { if (voteCount.get(s) > n) return "Invalid election"; } List<String> candidates = new ArrayList<>(); for (String s : students) { if (voteCount.get(s) == maxVotes) { candidates.add(s); } } Collections.sort(candidates); return candidates.get(0); } private static boolean isContinuousSubsequence(String[] voteTokens, String[] studentTokens) { int n = voteTokens.length; int m = studentTokens.length; if (n > m) return false; for (int i = 0; i <= m - n; i++) { boolean match = true; for (int j = 0; j < n; j++) { if (!voteTokens[j].equals(studentTokens[i + j])) { match = false; break; } } if (match) return true; } return false; } }3. C++ 实现
#include <vector> #include <string> #include <unordered_map> #include <algorithm> using namespace std; bool isContinuousSubsequence(vector<string>& voteTokens, vector<string>& studentTokens) { int n = voteTokens.size(); int m = studentTokens.size(); if (n > m) return false; for (int i = 0; i <= m - n; i++) { bool match = true; for (int j = 0; j < n; j++) { if (voteTokens[j] != studentTokens[i + j]) { match = false; break; } } if (match) return true; } return false; } string electMonitor(vector<string>& students, vector<string>& votes) { int n = students.size(); if (votes.size() > 3 * n) { return "Invalid election"; } unordered_map<string, vector<string>> studentTokens; unordered_map<string, int> voteCount; for (string s : students) { vector<string> tokens; size_t start = 0, end = s.find('-'); while (end != string::npos) { tokens.push_back(s.substr(start, end - start)); start = end + 1; end = s.find('-', start); } tokens.push_back(s.substr(start)); studentTokens[s] = tokens; voteCount[s] = 0; } for (string vote : votes) { vector<string> voteTokens; size_t start = 0, end = vote.find('-'); while (end != string::npos) { voteTokens.push_back(vote.substr(start, end - start)); start = end + 1; end = vote.find('-', start); } voteTokens.push_back(vote.substr(start)); if (voteTokens.empty()) continue; vector<string> matches; for (string s : students) { if (isContinuousSubsequence(voteTokens, studentTokens[s])) { matches.push_back(s); } } if (matches.size() == 1) { voteCount[matches[0]]++; } } int maxVotes = 0; for (auto& p : voteCount) { if (p.second > maxVotes) maxVotes = p.second; } if (maxVotes == 0) return "Invalid election"; for (string s : students) { if (voteCount[s] > n) return "Invalid election"; } vector<string> candidates; for (string s : students) { if (voteCount[s] == maxVotes) { candidates.push_back(s); } } sort(candidates.begin(), candidates.end()); return candidates[0]; }4. JavaScript 实现
function isContinuousSubsequence(voteTokens, studentTokens) { const n = voteTokens.length; const m = studentTokens.length; if (n > m) return false; for (let i = 0; i <= m - n; i++) { let match = true; for (let j = 0; j < n; j++) { if (voteTokens[j] !== studentTokens[i + j]) { match = false; break; } } if (match) return true; } return false; } function electMonitor(students, votes) { const n = students.length; if (votes.length > 3 * n) { return "Invalid election"; } const studentTokens = {}; const voteCount = {}; students.forEach(s => { studentTokens[s] = s.split('-'); voteCount[s] = 0; }); votes.forEach(vote => { const voteTokens = vote.split('-'); if (voteTokens.length === 0) return; const matches = []; students.forEach(s => { if (isContinuousSubsequence(voteTokens, studentTokens[s])) { matches.push(s); } }); if (matches.length === 1) { voteCount[matches[0]]++; } }); const maxVotes = Math.max(...Object.values(voteCount)); if (maxVotes === 0) return "Invalid election"; for (const s of students) { if (voteCount[s] > n) return "Invalid election"; } const candidates = students.filter(s => voteCount[s] === maxVotes); candidates.sort(); return candidates[0]; }5. Go 实现
package main import ( "sort" "strings" ) func isContinuousSubsequence(voteTokens, studentTokens []string) bool { n := len(voteTokens) m := len(studentTokens) if n > m { return false } for i := 0; i <= m-n; i++ { match := true for j := 0; j < n; j++ { if voteTokens[j] != studentTokens[i+j] { match = false break } } if match { return true } } return false } func electMonitor(students []string, votes []string) string { n := len(students) if len(votes) > 3*n { return "Invalid election" } studentTokens := make(map[string][]string) voteCount := make(map[string]int) for _, s := range students { studentTokens[s] = strings.Split(s, "-") voteCount[s] = 0 } for _, vote := range votes { voteTokens := strings.Split(vote, "-") if len(voteTokens) == 0 { continue } matches := []string{} for _, s := range students { if isContinuousSubsequence(voteTokens, studentTokens[s]) { matches = append(matches, s) } } if len(matches) == 1 { voteCount[matches[0]]++ } } maxVotes := 0 for _, count := range voteCount { if count > maxVotes { maxVotes = count } } if maxVotes == 0 { return "Invalid election" } for _, s := range students { if voteCount[s] > n { return "Invalid election" } } candidates := []string{} for _, s := range students { if voteCount[s] == maxVotes { candidates = append(candidates, s) } } sort.Strings(candidates) return candidates[0] }总结
以上实现均严格遵循题目要求:
- 使用分割字符串和连续子序列匹配处理选票。
- 检查总票数、单人选票上限等边界条件。
- 平票时按字典序排序选出班长。
- 所有无效情况返回固定字符串。
各语言版本逻辑一致,可直接用于实际场景。