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));
    }
}