Для начала, использование Int32
для сохранения числа означает, что оно не должно превышать 2,147,483,647 .И кроме этого, вы не сможете проверить начальный ноль после преобразования в число, поскольку начальные нули, очевидно, исчезают, когда вы получаете число.
Это означает, чтовы должны сохранить ввод как string
во время проверки.Это на самом деле облегчает вашу работу, поскольку вы можете индексировать отдельные символы без необходимости использования арифметических операций.
Поскольку вы работаете со строками, вам также следует проверить, содержит ли входная строка недопустимые (не цифры)символы перед чем-либо еще:
bool ContainsInvalidCharacters(string input)
{
// check if there is a non-digit character
foreach (char c in input)
if (!char.IsDigit(c))
return true;
return false;
}
Затем вы можете продолжить добавление отдельных правил.Например, чтобы проверить, повторяются ли символы, вы сделаете что-то вроде:
bool ContainsRepetitiveDigits(string input)
{
if (input.Length == 0)
return false;
// get the first character
char firstChar = input[0];
// check if there is a different character
foreach (char c in input)
if (c != firstChar)
return false;
// if not, it means it's repetitive
return true;
}
bool StartsWithZero(string input)
{
if (input.Length == 0)
return false;
return (input[0] == '0');
}
Чтобы обнаружить последовательности, самый простой способ - получить разницу первых двух символов, а затем проверить, изменяется ли она черезвся строка:
bool IsSequence(string input)
{
// we need at least two characters
// for a sequence
if (input.Length < 2)
return false;
// get the "delta" between first two
// characters
int difference = input[1] - input[0];
// allowed differences are:
// -1: descending sequence
// 0: repetitive digits
// 1: ascending sequence
if (difference < -1 || difference > 1)
return false;
// check if all characters are equally
// distributed
for (int i = 2; i < input.Length; i++)
if (input[i] - input[i - 1] != difference)
return false;
// this is a sequence
return true;
}
Как только вы определили все свои правила, вы можете создать один метод, который будет проверять их один за другим:
bool Validate(string input)
{
// list of all predicates to check
IEnumerable<Predicate<string>> rules = new Predicate<string>[]
{
ContainsInvalidCharacters,
ContainsRepetitiveDigits,
StartsWithZero,
IsSequence
};
// check if any rule matches
foreach (Predicate<string> check in rules)
if (check(input))
return false;
// if no match, it means input is valid
return true;
}
Обратите внимание, что IsSequence
обнаруживает также повторяющиеся цифры (когда разница символов равна нулю).Если вы хотите явно предотвратить это, измените условие, где проверяются разрешенные различия.Кроме того, вы можете полностью удалить правило ContainsRepetitiveDigits
.
[Редактировать]
Поскольку я вижу, что вы используете Java вместо C #, я попытаюсь привести лучший пример.
Отказ от ответственности: Я обычно не программирую на Java, но насколько я знаю, Java не поддерживает делегатов, как в C #.Поэтому я постараюсь предоставить пример Java (надеюсь, он будет работать), который лучше выражает мое намерение «составной проверки».
(следует подозрительный код Java)
Сначала определите интерфейс, который будут реализованы во всех правилах проверки:
// (java code)
/**
* Defines a validation rule.
*/
public interface IValidationRule
{
/**
* Returns a description of this
* validation rule.
*/
String getDescription();
/**
* Returns true if this rule
* is matched.
*/
boolean matches(String tpin);
}
Затем определите каждое правило в отдельном классе, реализуя методы getDescription
и matches
:
// (java code)
public class RepetitiveDigitsRule implements IValidationRule
{
public String getDescription()
{
return "TPIN contains repetitive digits";
}
public boolean matches(String tpin)
{
char firstChar = tpin.charAt(0);
for (int i = 1; i < tpin.length(); i++)
if (tpin.charAt(i) != firstChar)
return false;
return true;
}
}
public class StartsWithZeroRule implements IValidationRule
{
public String getDescription()
{
return "TPIN starts with zero";
}
public boolean matches(String tpin)
{
if (tpin.length() < 1)
return false;
return tpin.charAt(0) == '0';
}
}
Вы можете видеть, что matches
метод не выводит что-либо на консоль.Он просто возвращает true
, если правило соответствует, и оставляет его вызывающей стороне , чтобы решить, печатать ли его описание (в консоль, окно сообщения, веб-страницу и т. Д.).
НаконецВы можете создать все известные правила (реализации IValidationRule
) и проверить их одно за другим:
// (java code)
public class Validator
{
// instantiate all known rules
IValidationRule[] rules = new IValidationRule[] {
new RepetitiveDigitsRule(),
new StartsWithZeroRule()
};
// validate tpin using all known rules
public boolean validate(String tpin)
{
System.out.print("Validating TPIN " + tpin + "... ");
// for all known rules
for (int i = 0; i < rules.length; i++)
{
IValidationRule rule = rules[i];
// if rule is matched?
if (rule.matches(tpin))
{
// print rule description
System.out.println("Error: " + rule.getDescription());
return false;
}
}
System.out.println("Success.");
return true;
}
}
Я рекомендую попытаться следовать этому шаблону.Вы получите код, который будет намного проще использовать и поддерживать.