【问题标题】:Getting wrong range of numbers获取错误的数字范围
【发布时间】:2022-12-07 23:43:42
【问题描述】:

给定一对 2 个字符串 "2-4,6-8" 我想分开这两对并找到这些范围之间的所有数字。 所以第一对2-4应该还给我2, 3, 4 第二对6-8应该返回6, 7, 8

我试过下面的代码

 var splittedString = ln.Split(",");
 var firstPair = splittedString[0];
 var secondPair = splittedString[1];
 var splittedFirstPair = firstPair.Split("-");

 IEnumerable<int> firsPairRange = Enumerable.Range(
   Convert.ToInt32(splittedFirstPair[0]), 
   Convert.ToInt32(splittedFirstPair[1]));

 var splittedSecondPair = secondPair.Split("-");

 IEnumerable<int> secondPairRange = Enumerable.Range(
   Convert.ToInt32(splittedSecondPair[0]), 
   Convert.ToInt32(splittedSecondPair[1]));

但变数第一对范围给我输出 2,3,4,5 和变量第二对范围给我输出6,7,8,9,10,11,12,13

我不明白为什么以及如何解决它?

【问题讨论】:

  • Enumerable.Range 的第二个参数是数数的值,而不是范围的终点。

标签: c# range


【解决方案1】:

Enumerable.Range有两个参数:

  • 开始
  • 计数(!)

因此,这已经为您提供了足够的信息来修复它。由于2-4,你的开始是 2,计数是 4,但你想要 4-2+1=3 作为计数:

IEnumerable<int> firstPairRange = Enumerable.Empty<int>();
if (splittedFirstPair.Length == 2 
   && int.TryParse(splittedFirstPair[0], out int first) 
   && int.TryParse(splittedFirstPair[1], out int second)
   && second >= first)
{
    int count = second - first + 1;
    firstPairRange = Enumerable.Range(first, count);
}

【讨论】:

  • 你可能想要 3 作为计数,而不是 2
  • @TZHX:是的,已经修复了
【解决方案2】:

一般情况(负数,单数)当我们允许这样的字符串时

    -9,2-4,6-8,-5,7,-3-5,-8--2

我们可以把它写成

    private static IEnumerable<IEnumerable<int>> Ranges(string text) {
        foreach (var range in text.Split(',')) {
            var match = Regex.Match(range, 
              @"^s*(?<left>-?[0-9]+)s*-s*(?<right>-?[0-9]+)s*$");

            if (match.Success) {
                int left = int.Parse(match.Groups["left"].Value);
                int right = int.Parse(match.Groups["right"].Value);

                yield return Enumerable.Range(left, right - left + 1);
            }
            else
                yield return new[] { int.Parse(range) };
        }
    }

演示:

    string text = "-9,2-4,6-8,-5,7,-3-5,-8--2";

    var result = string.Join(Environment.NewLine, Ranges(text)
      .Select(range => string.Join(", ", range)));

    Console.Write(result);

输出:

-9
2, 3, 4
6, 7, 8
-5
7
-3, -2, -1, 0, 1, 2, 3, 4, 5
-8, -7, -6, -5, -4, -3, -2

【讨论】:

    【解决方案3】:
    string ln = "2-4,6-8";
    var splittedString = ln.Split(',').Select(x => x.Split('-').Select(int.Parse).ToArray());
    int[] first = splittedString.ElementAt(0);
    int[] second = splittedString.ElementAt(1);
    var firstPairRange = Enumerable.Range(first[0], first[1] - first[0] + 1);
    var secondPairRange = Enumerable.Range(second[0], second[1] - second[0] + 1);
    

    【讨论】:

    • 为什么不解释为什么这是一个正确的答案,而不仅仅是转储代码解决方案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多