CS50x DNA PSET5技术问题:如何根据匹配的STR数值获取对应人名
解决CS50x DNA PSET5:匹配STR数值对应的人名
原代码问题分析
你当前的匹配逻辑(用集合求交集)存在根本性错误:集合会忽略元素顺序且只保留共同元素,无法保证所有STR数值完全匹配——比如不同用户可能有部分相同的STR数值,但并非全部吻合,这种方式会导致错误匹配或漏匹配。
修正方案
正确的思路是逐行遍历数据库中的用户数据,对比该用户的所有STR数值与你计算出的find_STR是否完全一致:
- 读取CSV后,第一行是STR类型表头,后续每行是「人名+对应STR数值」
- 将计算出的
find_STR(整数列表)转换为字符串列表,与CSV中的数值格式统一 - 遍历每个用户数据,对比其STR数值列表与计算结果,找到完全匹配的用户并输出人名
- 若遍历完无匹配,输出
No match
修正后的完整代码
import csv import sys def main(): # 检查命令行参数 if len(sys.argv) != 3: print("Usage: python dna.py data.csv sequence.txt") sys.exit(1) filecsv = sys.argv[1] filetext = sys.argv[2] # 读取CSV数据库 with open(filecsv, "r") as csvfile: reader = csv.reader(csvfile) db = list(reader) # db[0]是STR表头,db[1:]是用户数据 # 读取DNA序列 with open(filetext, "r") as file: sequence = file.read() # 计算每个STR的最长匹配次数 find_STR = [] # 遍历所有STR类型(跳过表头第一个元素"name") for str_type in db[0][1:]: find_STR.append(longest_match(sequence, str_type)) # 转换为字符串,与CSV中的数值格式统一 str_find = [str(num) for num in find_STR] # 匹配数据库中的用户 for user in db[1:]: # user[0]是人名,user[1:]是该用户的STR数值列表 if user[1:] == str_find: print(user[0]) return # 无匹配情况 print("No match") def longest_match(sequence, subsequence): """Returns length of longest run of subsequence in sequence.""" longest_run = 0 subsequence_length = len(subsequence) sequence_length = len(sequence) for i in range(sequence_length): count = 0 while True: start = i + count * subsequence_length end = start + subsequence_length if start >= sequence_length: break if sequence[start:end] == subsequence: count += 1 else: break longest_run = max(longest_run, count) return longest_run if __name__ == "__main__": main()
关键代码说明
- 命令行参数检查:确保用户输入正确的文件路径,避免因参数错误导致程序崩溃
- 数据库遍历逻辑:
db[1:]取出所有用户数据,user[1:]获取该用户的所有STR数值,直接与str_find对比是否完全相等,保证顺序和数值都匹配 - 格式统一:将计算出的整数转换为字符串,与CSV中存储的字符串格式对齐,避免类型不匹配导致的对比失败
内容的提问来源于stack exchange,提问作者guizin
相关产品推荐
相关产品推荐

