Closed. This question needs debugging details 。它目前不接受答案。
想改善这个问题吗?更新问题,使其成为 Stack Overflow 的 on-topic。
5年前关闭。
Improve this question
不知道为什么问题被标记为离题,所谓的期望行为包含在问题帖子中!
我正在尝试编写这个需要两个输入的程序:
• 一组包含间隔
• 和一组排除区间
间隔集合可以按任何顺序给出,它们可以是空的或重叠的。程序应该输出所有包含和“删除”排除的结果。输出应以排序顺序作为非重叠间隔给出。
间隔将仅包含整数
例子 :
包括:50-600、10-100
不包括:(空)
产量:10-600
包括:10-100、200-300、400-600
不包括:95-205、410-420
输出:10-94、206-300、400-409、421-600
我试图从 include 和 excludes 填充两个 Enumerable Range (在 splitting,parsing 之后),但没有找到任何有效的方法来实现它。
任何输入都会有很大帮助
想改善这个问题吗?更新问题,使其成为 Stack Overflow 的 on-topic。
5年前关闭。
Improve this question
不知道为什么问题被标记为离题,所谓的期望行为包含在问题帖子中!
我正在尝试编写这个需要两个输入的程序:
• 一组包含间隔
• 和一组排除区间
间隔集合可以按任何顺序给出,它们可以是空的或重叠的。程序应该输出所有包含和“删除”排除的结果。输出应以排序顺序作为非重叠间隔给出。
间隔将仅包含整数
例子 :
包括:50-600、10-100
不包括:(空)
产量:10-600
包括:10-100、200-300、400-600
不包括:95-205、410-420
输出:10-94、206-300、400-409、421-600
我试图从 include 和 excludes 填充两个 Enumerable Range (在 splitting,parsing 之后),但没有找到任何有效的方法来实现它。
string[] _break = _string.Split(',');
string[] _breakB = _stringB.Split(',');
string[] res = new string[_break.Length + 1];
string[] _items, _itemsB;
List < int > _back = new List < int > ();
int count = 0;
foreach(var _item in _break) {
_items = _item.Split('-');
var a = Enumerable.Range(int.Parse(_items[0]), (int.Parse(_items[1]) - int.Parse(_items[0]) + 1)).ToList();
foreach(var _itemB in _breakB) {
_itemsB = _itemB.Split('-');
var b = Enumerable.Range(int.Parse((_itemsB[0])), (int.Parse(_itemsB[1]) - int.Parse((_itemsB[0])) + 1)).ToList();
var c = a.Except < int > (b).ToList();
/// different things tried here, but they are not good
res[count] = c.Min().ToString() + "-" + c.Max().ToString();
count++;
}
}
return res;
任何输入都会有很大帮助
最佳答案
这应该比 SortedSet 技巧工作得更快,至少在大间隔内是这样。想法是这样的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Test
{
using Pair = Tuple<int, int>; //for brevity
struct Point //point of an interval
{
public enum Border { Left, Right };
public enum Interval { Including, Excluding };
public int Val;
public int Brdr;
public int Intr;
public Point(int value, Border border, Interval interval)
{
Val = value;
Brdr = (border == Border.Left) ? 1 : -1;
Intr = (int)interval;
}
public override string ToString() =>
(Brdr == 1 ? "L" : "R") + (Intr == 0 ? "+ " : "- ") + Val;
}
class Program
{
static IEnumerable<Pair> GetInterval(string strIn, string strEx)
{
//a func to get interval border points from string:
Func<string, Point.Interval, IEnumerable<Point>> parse = (str, intr) =>
Regex.Matches(str, "[0-9]+").Cast<Match>().Select((s, idx) =>
new Point(int.Parse(s.Value), (Point.Border)(idx % 2), intr));
var INs = parse(strIn, Point.Interval.Including);
var EXs = parse(strEx, Point.Interval.Excluding);
var intrs = new int[2]; //current interval border control IN[0], EX[1]
int start = 0; //left border of a new resulting interval
//put all points in a line and loop:
foreach (var p in INs.Union(EXs).OrderBy(x => x.Val))
{
//check for start (close) of a new (cur) interval:
var change = (intrs[p.Intr] == 0) ^ (intrs[p.Intr] + p.Brdr == 0);
intrs[p.Intr] += p.Brdr;
if (!change) continue;
var In = p.Intr == 0 && intrs[1] == 0; //w no Ex
var Ex = p.Intr == 1 && intrs[0] > 0; //breaks In
var Open = intrs[p.Intr] > 0;
var Close = !Open;
if (In && Open || Ex && Close)
{
start = p.Val + p.Intr; //exclude point if Ex
}
else if (In && Close || Ex && Open)
{
yield return new Pair(start, p.Val - p.Intr);
}
}
}
static void Main(string[] args)
{
var strIN = "10-100, 200-300, 400-500, 420-480";
var strEX = "95-205, 410-420";
foreach (var i in GetInterval(strIN, strEX))
Console.WriteLine(i.Item1 + "-" + i.Item2);
Console.ReadLine();
}
}
}
关于c# - 将范围序列拆分为多个字符串 c#,linq,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35104036/
10-10 21:42