Prolog代码修改求助:提取姓名首3字母及支持多姓名输入
解决Prolog多姓名输入与姓名代码生成问题
首先咱们拆解下你遇到的两个核心问题:
read/1只能读取单个Prolog项(比如单个原子),输入多个姓名时会被当成多个独立项,直接触发语法错误- 需要提取每个姓名的首字母(从你的期望输出
PJM来看,是每个姓名的首字母大写拼接,如果你确实要前3个字母的话可以调整)并生成姓名代码
下面是修改后的完整代码,我会逐段解释:
name :- % 读取整行输入,转换成字符码列表 read_line_to_codes(user_input, InputCodes), % 将字符码列表分割成原子列表(每个原子对应一个姓名) split_string(InputCodes, " ", "", NameAtoms), % 打印输入的姓名列表 write('Name : '), write(NameAtoms), nl, % 生成并打印姓名代码 generate_name_code(NameAtoms, Code), write('Name Code : '), write(Code), nl. % 递归生成姓名代码:遍历每个姓名,取首字母大写后拼接 generate_name_code([], ""). generate_name_code([Name|Rest], Code) :- % 把姓名原子拆成字符列表,取第一个字符 atom_chars(Name, [FirstChar|_]), % 将首字符转为大写 upcase_atom(FirstChar, UpperChar), % 递归处理剩余姓名 generate_name_code(Rest, RestCode), % 拼接当前大写字母与剩余代码 atom_concat(UpperChar, RestCode, Code).
代码细节说明:
- 读取整行输入:用
read_line_to_codes/2读取整行输入的字符码,彻底解决read/1只能读单个项的问题,输入peter jane mary会被当成一整行完整处理。 - 分割姓名列表:
split_string/4把整行字符码按空格分割成单个姓名的原子列表,比如输入会被转成[peter,jane,mary]。 - 生成姓名代码:通过递归遍历每个姓名,提取首字母转大写后拼接,最终得到你需要的
PJM格式代码。
测试效果:
| ?- name. |: peter jane mary. Name : [peter,jane,mary] Name Code : PJM yes
如果你确实需要提取每个姓名的前3个字母(而非首字母),只需要修改generate_name_code/2的逻辑,新增一个辅助谓词来截取前3个字符:
generate_name_code([], ""). generate_name_code([Name|Rest], Code) :- atom_chars(Name, Chars), % 取姓名的前3个字符,不足3个则取全部 take(3, Chars, FirstThree), atom_chars(FirstThreeAtom, FirstThree), upcase_atom(FirstThreeAtom, UpperThree), generate_name_code(Rest, RestCode), atom_concat(UpperThree, RestCode, Code). % 辅助谓词:截取列表的前N个元素 take(0, _, []). take(_, [], []). take(N, [H|T], [H|Rest]) :- N > 0, N1 is N - 1, take(N1, T, Rest).
这时输入peter jane mary会输出Name Code : PETJANMAR。
内容的提问来源于stack exchange,提问作者EddieJn
相关产品推荐
相关产品推荐

