1

我在下面有这个 Prolog 程序,它检查密码是否符合某些规则(密码必须包含字母(az)、数字(0-9)、双字母(aa、ll、ww 等),必须开始带有字母(a、aa、c 等),长度必须至少为 6 个字符)。

如何扩展它以便将双字母计为一个字母?(例如,aa25b1 不是正确的密码,因为它只有五个字符长)。

contains_letter(Password) :- wildcard_match('*[a-zA-Z]*', Password).

contains_number(Password) :- wildcard_match('*[0-9]*', Password).

contains_double_letter(Password) :-
    (between(65, 90, Letter) ; between(97, 122, Letter)),
    append([_, [Letter, Letter], _], Password),
    !.

starts_with_letter(Password) :- wildcard_match('[a-zA-Z]*', Password).

long_enough(Password) :-
    length(Password, Length),
    Length >= 6.

check_everything(Password) :-
    contains_letter(Password),
    contains_number(Password),
    contains_double_letter(Password),
    starts_with_letter(Password),
    long_enough(Password).
4

3 回答 3

3

使用将相等字符压缩在一起的谓词预处理密码,例如

uniq([], []).
uniq([X], [X]).
uniq([X,X|L], R) :-
     !,
     uniq([X|L], R).
uniq([X,Y|L], [X|R]) :-
     uniq([Y|L], R).

(我以 Unix 工具uniq命名它;您可能想要重命名它without_adjacent_repetitions或其他更符合您口味的名称。)

于 2011-12-05T15:18:49.737 回答
2

编写您自己的 lengthWithDoubleLetters/2 规则,获取字符列表并将其长度计算为双字母:

lengthWithDoubleLetters([],0).
lengthWithDoubleLetters([F,F|T],C) :-
    lengthWithDoubleLetters(T,TC),
    !,
    C is TC + 1.
lengthWithDoubleLetters([H|T], C) :-
    lengthWithDoubleLetters(T,TC),
    C is TC + 1.
于 2011-12-05T15:25:51.553 回答
2

首先,正如我在您的第一个问题中所说的那样,请注意您可以将其结合起来:

contains_letter(Password) :- wildcard_match('*[a-zA-Z]*', Password).

contains_number(Password) :- wildcard_match('*[0-9]*', Password).

starts_with_letter(Password) :- wildcard_match('[a-zA-Z]*', Password).

进入那个:

letter_start_and_number(Password) :-
    wildcard_match('[a-zA-Z]*[0-9]*', Password).

现在,您可以按如下方式处理双字母和长度:

length_double_letters([], Acc, yes, Acc).
length_double_letters([Char, Char|Password], Acc, _Contains, Length) :-
    !,
    NewAcc is Acc + 1,
    length_double_letters(Password, NewAcc, yes, Length).
length_double_letters([_Char|Password], Acc, Contains, Length) :-
    NewAcc is Acc + 1,
    length_double_letters(Password, NewAcc, Contains, Length).

在这个主要谓词中使用该谓词:

check_everything(Password) :-
    letter_start_and_number(Password),
    length_double_letters(Password, 0, no, Length),
    Length >= 6.

PS:请花时间接受您认为最有建设性的答案,并为对您有帮助的答案投赞成票。

于 2011-12-05T21:46:40.187 回答