C# 确定int是在列表中还是在范围中
如何确定给定的C# 确定int是在列表中还是在范围中,c#,C#,如何确定给定的int是否对应于给定的“模式”。“模式”可以由int或int的范围组成 这是该方法的签名 //Eg of pattern // 10,12,14,16 // [10-20];21;23 public bool IsInPattern(int inputToTest, string pattern) { //Todo } 下面的模式定义为一个字符串,其中包含由“;”分隔的内部模式列表。内部模式可以是整型,也可以是范围
int
是否对应于给定的“模式”。“模式”可以由int或int的范围组成
这是该方法的签名
//Eg of pattern
// 10,12,14,16
// [10-20];21;23
public bool IsInPattern(int inputToTest, string pattern)
{
//Todo
}
下面的模式定义为一个字符串,其中包含由“;”分隔的内部模式列表。内部模式可以是整型,也可以是范围[lowerBound upperBound]
我相信用regex可以做到这一点,但我没有成功。另外,我更喜欢一个比类似于
的解决方案更优雅的解决方案,如果子模式.StartWith('['),那么lowerBound=subPattern.Substring
等…可能类似于:
pattern.Split(',').Where(sub=>sub == inputToTest.ToString())
如果存在一个范围或任意整数序列,并由预定义的分隔符(在本例中)分隔,则此方法非常有效。可能类似于:
pattern.Split(',').Where(sub=>sub == inputToTest.ToString())
如果存在一个范围或任意整数序列,并由一些预定义的分隔符(在这个具体的例子中)分隔,那么这种方法非常有效。我将把它写成两种方法,而不是模式
public bool IsInSequence(int inputToTest, IEnumerable<int> sequence)
{
return sequence.Contains(inputToTest);
}
public bool IsInRange(int inputToTest, int start, int end)
{
return inputToTest>= start && inputToTest<=end ;
}
public bool isnsequence(int-input-test,IEnumerable-sequence)
{
返回序列。包含(inputToTest);
}
公共布尔值范围(整数输入测试、整数开始、整数结束)
{
return inputToTest>=start&&inputToTest我将把它写成两个方法,而不是一个模式
public bool IsInSequence(int inputToTest, IEnumerable<int> sequence)
{
return sequence.Contains(inputToTest);
}
public bool IsInRange(int inputToTest, int start, int end)
{
return inputToTest>= start && inputToTest<=end ;
}
public bool isnsequence(int-input-test,IEnumerable-sequence)
{
返回序列。包含(inputToTest);
}
公共布尔值范围(整数输入测试、整数开始、整数结束)
{
return inputToTest>=start&&inputToTest您可以使用这样一个简单的解析
public bool IsInPattern(int inputToTest, string pattern)
{
var numbers = new List<int>();
var tokens = pattern.Split(new []{",", " ", "or"},
StringSplitOptions.RemoveEmptyEntries);
bool to_flag = false;
foreach(var t in tokens)
{
int n;
if (Int32.TryParse(t, out n))
{
if (to_flag)
numbers.AddRange(Enumerable.Range(numbers.Last() + 1,
n - numbers.Last()));
else
numbers.Add(n);
to_flag = false;
}
else if (t == "to") to_flag = true;
else throw new Exception("invalid pattern");
}
return numbers.Contains(inputToTest);
}
您可以使用这样一个简单的解析
public bool IsInPattern(int inputToTest, string pattern)
{
var numbers = new List<int>();
var tokens = pattern.Split(new []{",", " ", "or"},
StringSplitOptions.RemoveEmptyEntries);
bool to_flag = false;
foreach(var t in tokens)
{
int n;
if (Int32.TryParse(t, out n))
{
if (to_flag)
numbers.AddRange(Enumerable.Range(numbers.Last() + 1,
n - numbers.Last()));
else
numbers.Add(n);
to_flag = false;
}
else if (t == "to") to_flag = true;
else throw new Exception("invalid pattern");
}
return numbers.Contains(inputToTest);
}
您可以尝试类似的方法(这是来自head,因此如果不进行修改,它可能无法工作):
public bool-IsInPattern(int-inputToTest,字符串模式)
{
if(pattern.Contains(“,”))
返回模式.Split(',).Contains(inputToTest.ToString());
其他的
{
var temp=模式分割(“;”);
if(临时包含(inputToTest.ToString()))
返回true;
其他的
{
temp=temp.RemoveAll(x=>!x.Contains(“-”);
foreach(温度中的变量x)
{
字符串[]a=x.Split(“-”).Select(x=>x.Trim('[',']')).ToArray();
if(IsInRange(inputToTest,int.Parse(a[0]),int.Parse(a[1]))
返回true;
}
}
}
返回false;
}
公共布尔值范围(整数输入测试、整数开始、整数结束)
{
return inputToTest>=start&&inputToTest您可以尝试类似的方法(这是从head获得的,因此如果不进行修改,它可能无法工作):
public bool-IsInPattern(int-inputToTest,字符串模式)
{
if(pattern.Contains(“,”))
返回模式.Split(',).Contains(inputToTest.ToString());
其他的
{
var temp=模式分割(“;”);
if(临时包含(inputToTest.ToString()))
返回true;
其他的
{
temp=temp.RemoveAll(x=>!x.Contains(“-”);
foreach(温度中的变量x)
{
字符串[]a=x.Split(“-”).Select(x=>x.Trim('[',']')).ToArray();
if(IsInRange(inputToTest,int.Parse(a[0]),int.Parse(a[1]))
返回true;
}
}
}
返回false;
}
公共布尔值范围(整数输入测试、整数开始、整数结束)
{
return inputToTest>=start&&inputToTest当我需要检查某个值是否满足不同条件时,我喜欢使用。规范如下所示:
public interface ISpecification<T>
{
bool IsSatisfiedBy(T value);
}
值列表(我们也可以考虑单个值作为列表规范):
但为了构建更有趣的条件,您需要实现条件逻辑:
public class OrSpecification<T> : ISpecification<T>
{
private readonly ISpecification<T> _left;
private readonly ISpecification<T> _right;
public OrSpecification(ISpecification<T> left, ISpecification<T> right)
{
_right = right;
_left = left;
}
public bool IsSatisfiedBy(T value)
{
return _left.IsSatisfiedBy(value) || _right.IsSatisfiedBy(value);
}
}
我们现在只需要从字符串中解析规范:
public class SpecificationParser
{
public static ISpecification<int> Parse(string input)
{
var parts = input.Split(';');
return parts.Aggregate(ParseSpec(parts[0]),
(spec, s) => spec.Or(ParseSpec(s)));
}
private static ISpecification<int> ParseSpec(string s)
{
var match = Regex.Match(s, @"\[(\d+)-(\d+)\]");
if (match.Success)
{
int from = Int32.Parse(match.Groups[1].Value);
int to = Int32.Parse(match.Groups[2].Value);
return new RangeSpecification(from, to);
}
return new InSpecification(s.Split(',').Select(Int32.Parse).ToArray());
}
}
我喜欢在需要检查某个值是否满足不同条件时使用。规范如下所示:
public interface ISpecification<T>
{
bool IsSatisfiedBy(T value);
}
值列表(我们也可以考虑单个值作为列表规范):
但为了构建更有趣的条件,您需要实现条件逻辑:
public class OrSpecification<T> : ISpecification<T>
{
private readonly ISpecification<T> _left;
private readonly ISpecification<T> _right;
public OrSpecification(ISpecification<T> left, ISpecification<T> right)
{
_right = right;
_left = left;
}
public bool IsSatisfiedBy(T value)
{
return _left.IsSatisfiedBy(value) || _right.IsSatisfiedBy(value);
}
}
我们现在只需要从字符串中解析规范:
public class SpecificationParser
{
public static ISpecification<int> Parse(string input)
{
var parts = input.Split(';');
return parts.Aggregate(ParseSpec(parts[0]),
(spec, s) => spec.Or(ParseSpec(s)));
}
private static ISpecification<int> ParseSpec(string s)
{
var match = Regex.Match(s, @"\[(\d+)-(\d+)\]");
if (match.Success)
{
int from = Int32.Parse(match.Groups[1].Value);
int to = Int32.Parse(match.Groups[2].Value);
return new RangeSpecification(from, to);
}
return new InSpecification(s.Split(',').Select(Int32.Parse).ToArray());
}
}
这是一个使用iPatterNinterpreter的不同实现的解决方案。PatternInterpreter的解释方法输入字符串表达式,并通过处理字符串表达式返回其Func表示
您应该为每种不同类型的模式字符串实现IPatternInterpretter。毕竟,您可以编写一个PatternInterpretterFactory来输入单个字符串模式并决定实例化哪个解释程序
class Program
{
static void Main(string[] args)
{
const string commaSeperatedPattern = "10,12,14,16";
const string literallyExpressedPattern = "10 to 20 or 21 or 23";
int input = 10;
var commaSeperatedFunc = new CommaSeperatedPatternInterpretter().Interpret(commaSeperatedPattern);
var literallyExpressedFunc = new LiterallyExpressedPatternInterpretter().Interpret(literallyExpressedPattern);
Console.WriteLine(string.Format("CommaSeperatedResult: {0} \nLiterallyExpressedResult: {1}",
commaSeperatedFunc(input),
literallyExpressedFunc(input)));
Console.ReadKey();
}
}
public interface IPatternInterpretter
{
Func<int, bool> Interpret(string pattern);
}
/// <summary>
/// Patterns like "10,12,14,16"
/// </summary>
public class CommaSeperatedPatternInterpretter : IPatternInterpretter
{
public Func<int, bool> Interpret(string pattern)
{
Func<int, bool> result = (input) => pattern.Split(',').Select(x => int.Parse(x.Trim())).Contains(input);
return result;
}
}
/// <summary>
/// Patterns like "10 to 20 or 21 or 23"
/// </summary>
public class LiterallyExpressedPatternInterpretter : IPatternInterpretter
{
public Func<int, bool> Interpret(string pattern)
{
Func<int, bool> result = (x) => false;
List<string> items = pattern.Split(' ').Select(x => x.Trim().ToLower()).ToList();
var ors = new List<int>();
var intervals = new List<Array>();
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
if (item.Equals("or") && i < items.Count-1)
{
ors.Add(int.Parse(items[i + 1]));
}
else if (item.Equals("to") && i < items.Count-1 && i > 0)
{
intervals.Add(new int[] {int.Parse(items[i - 1]), int.Parse(items[i + 1])});
}
}
return x => ors.Contains(x) || intervals.Any(i => x > (int) i.GetValue(0) && x < (int) i.GetValue(1));
}
}
类程序
{
静态void Main(字符串[]参数)
{
常量字符串commaseOperatedPattern=“10,12,14,16”;
常量字符串literallyExpressedPattern=“10到20或21或23”;
int输入=10;
var CommaseOperatedFunc=新的CommaseOperatedPatternInterpretatter().Explorate(CommaseOperatedPattern);
var literallyExpressedFunc=新的LiterallyExpressedPatternInterpretater().Explorate(literallyExpressedPattern);
Console.WriteLine(string.Format(“CommaseOperatedResult:{0}\nLiterallyExpressedResult:{1}”),
CommaseOperatedFunc(输入),
literallyExpressedFunc(输入));
Console.ReadKey();
}
}
公共接口iPatterNinterpreter
{
Func解释(字符串模式);
}
///
///像“10,12,14,16”这样的模式
///
公共类CommaseOperatedPattern解释器:iPatternInterpreter
{
公共函数解释(字符串模式)
{
Func result=(输入)=>pattern.Split(',).Select(x=>int.Parse(x.Trim()).Contains(输入);
返回结果;
}
}
///
///像“10到20或21或23”这样的模式
///
公共类LiterallyExpressedPatternInterpreter:iPatternInterpreter
{
公共函数解释(字符串模式)
{
Func结果=(x)=>false;
L
var spec1 = SpecificationParser.Parse("10, 12, 14, 16");
spec1.IsSatisfiedBy(11); // false
var spec2 = SpecificationParser.Parse("[10-20];21;23,25");
spec2.IsSatisfiedBy(9); // false
spec2.IsSatisfiedBy(19); // true
spec2.IsSatisfiedBy(22); // false
class Program
{
static void Main(string[] args)
{
const string commaSeperatedPattern = "10,12,14,16";
const string literallyExpressedPattern = "10 to 20 or 21 or 23";
int input = 10;
var commaSeperatedFunc = new CommaSeperatedPatternInterpretter().Interpret(commaSeperatedPattern);
var literallyExpressedFunc = new LiterallyExpressedPatternInterpretter().Interpret(literallyExpressedPattern);
Console.WriteLine(string.Format("CommaSeperatedResult: {0} \nLiterallyExpressedResult: {1}",
commaSeperatedFunc(input),
literallyExpressedFunc(input)));
Console.ReadKey();
}
}
public interface IPatternInterpretter
{
Func<int, bool> Interpret(string pattern);
}
/// <summary>
/// Patterns like "10,12,14,16"
/// </summary>
public class CommaSeperatedPatternInterpretter : IPatternInterpretter
{
public Func<int, bool> Interpret(string pattern)
{
Func<int, bool> result = (input) => pattern.Split(',').Select(x => int.Parse(x.Trim())).Contains(input);
return result;
}
}
/// <summary>
/// Patterns like "10 to 20 or 21 or 23"
/// </summary>
public class LiterallyExpressedPatternInterpretter : IPatternInterpretter
{
public Func<int, bool> Interpret(string pattern)
{
Func<int, bool> result = (x) => false;
List<string> items = pattern.Split(' ').Select(x => x.Trim().ToLower()).ToList();
var ors = new List<int>();
var intervals = new List<Array>();
for (int i = 0; i < items.Count; i++)
{
var item = items[i];
if (item.Equals("or") && i < items.Count-1)
{
ors.Add(int.Parse(items[i + 1]));
}
else if (item.Equals("to") && i < items.Count-1 && i > 0)
{
intervals.Add(new int[] {int.Parse(items[i - 1]), int.Parse(items[i + 1])});
}
}
return x => ors.Contains(x) || intervals.Any(i => x > (int) i.GetValue(0) && x < (int) i.GetValue(1));
}
}