加上或减去“1,2,4,10-25,40 +”+“3,11,26”等范围的集合

时间:2015-06-19 16:22:10

标签: c# collections range

我正在编写一个C#程序,用户可以在其中输入一系列值,例如“1,2,4,10-25,40 +”,其中项目可以是单个数字,范围如10-25 ,范围到无穷大,如25+。范围必须至少相隔2,你不能说10-11,那应该是10,11。 我需要添加和减去它们的函数。

例如,“1,2,4,10-25,40 +”+“3,11,26”将返回“1-4,10-26,40 +”

我在这里使用字符串作为示例目的,但假设数据已经被解析为三个类别的对象:单个数字,范围,无限范围。我不是在问如何解析字符串。

我正在编写自己的一组函数,并且由于范围必须相隔2,因此存在很多复杂性。我知道有一些函数可以测试一个数字是否在一个范围内,并且很容易构建一个例程来测试一个数字是否在一组范围内。

但是我如何添加或减去集合,并简化它们,这样你就不会得到11,12,13而是11-13?这不是微不足道的。我对任何解决方案持开放态度,如果需要,我可以导入库。

3 个答案:

答案 0 :(得分:0)

这是我写的一个小功能,可以帮助你...... fiddle

private static List<string> Simplify(List<string> inputs)
{
    var simpleList = new List<int>();
    var retval = new List<string>();
    bool infinity = false;

    foreach (string input in inputs)
    {
        if (string.IsNullOrEmpty(input))
            continue;

        if (input.Split('-').Length > 1)
        {
            int min = int.Parse(input.Split('-')[0].Trim());
            int max = int.Parse(input.Split('-')[1].Trim());

            // inclusive
            simpleList.AddRange(Enumerable.Range(min, max - min + 1));

            continue;
        }

        if (input.Trim().EndsWith("+"))
        {
            infinity = true;
            simpleList.Add(int.Parse(input.Trim().Trim('+')));
        } else simpleList.Add(int.Parse(input.Trim()));
    }

    simpleList.Sort();

    for (int i = 0; i < simpleList.Count; i++)
    {
        int currentVal = simpleList[i];
        int q = i;
        while (q < simpleList.Count)
        {
            if (q != simpleList.Count - 1 && simpleList[q] + 1 == simpleList[q + 1])
            {
                q++;
                continue;
            }
            if (currentVal == simpleList[q])
            {
                retval.Add(currentVal.ToString());
                i = q;
                break;
            }
            if (currentVal + 1 == simpleList[q])
            {
                retval.Add(currentVal.ToString());
                retval.Add(simpleList[q].ToString());
                i = q;
                break;
            }
            retval.Add(currentVal + "-" + simpleList[q]);
            i = q;
            break;
        }
    }

    if (infinity)
        retval[retval.Count - 1] = retval[retval.Count - 1] + "+";

    return retval;
}

测试用例:

var inputs = new List<string> {"11", "12", "13", "14-18", "2-3", "25", "82+", "9"};

var simplifiedList = Simplify(inputs);

foreach (string input in simplifiedList)
{
    Console.WriteLine(input);
}

输出:

2
3
9
11-18
25
82+

答案 1 :(得分:0)

所以这是我的一组功能。 我将序列项定义为整数列表(所有正BTW),其中单个num是(num),range是(start end),无限范围是(num -1)。 在字符串中,我允许 - 或|用于范围分隔符。 我可能省略了几种扩展方法,但我认为我得到了它们。 我知道这些空间在网上看起来很难看,你需要复制并粘贴到.cs文件中才能看得很清楚。我jsut从VS复制和粘贴。

进行测试,尝试这样的事情:(他们故意有奇数值......)

列表&gt; result = AddSequences(StringToSequence(“10,11,12-14,20-30,40 +”),StringToSequence(“15,16,21-41,50 +”));

列表&gt; result = SubtractSequences(StringToSequence(“10,11,20-30,40 +”),StringToSequence(“21-41,50 +”));

列表&gt; result = StringToSequence(“1-5,8,10,11-29,30 +,19-25,30-40,50 +,60 +”);

    //-------------------sequence tools-----------------------------
    public static string SequenceToString(List<List<int>> seq) {
    string ret = "";
    foreach (List<int> pair in seq) {
        if (pair.Count == 1)
        ret = ret + pair[0].ToString() + ",";
        else {
        if (pair[1] != -1)
            ret = ret + pair[0].ToString() + "|" + pair[1].ToString() + ",";
        else
            ret = ret + pair[0].ToString() + "+,";
        }
    }
    return ret;
    }

public static List<List<int>> StringToSequence(string seq) {
    List<List<int>> ret = new List<List<int>>();
    //make sure we have a list of integers
    //turn into a List<List<int>>
    //use -1 as second item to indicate the +
    List<List<int>> pairs = new List<List<int>>();
    //int usesPlus = -1;
    //split by commas
    string[] items = seq.RemoveCharsExcept("|.,-+").Split(',');
    foreach (string str in items) {
    //see if we have a dash
    if (str.Contains("-") || str.Contains("|")) {
        string[] tmp1;
        if (str.Contains("-"))
        tmp1 = str.Split('-');
        else 
        tmp1 = str.Split('|');
        //the RemoveChars() is to get rid of a + if there
        if (tmp1.Count() == 2 && tmp1[0].RemoveChars().IsInteger() && tmp1[1].RemoveChars().IsInteger()) {
        int int1 = tmp1[0].RemoveChars().ToInteger();
        int int2 = tmp1[1].RemoveChars().ToInteger();
        if (int2 > int1)
            if (int2 - int1 == 1) {
            pairs.Add(new List<int>() { int1 });
            pairs.Add(new List<int>() { int2 });
            }
            else
            pairs.Add(new List<int>() { int1, int2 });
        }
    }
    else if (str.RemoveChars().IsInteger()) {
        int tmp = str.RemoveChars().ToInteger();
        if (str.Right(1) == "+")
        pairs.Add(new List<int>() { str.RemoveChars().ToInteger(), -1 });
        else
        pairs.Add(new List<int>() { str.RemoveChars().ToInteger() });
    }
    }
    //now sort list by first item
    ret = pairs.OrderBy(o => o[0]).ToList();
    DelSequenceDupes(ret);
    CombineSequenceNums(ret);
    CombineSequenceMergeNumsToSeqs(ret);
    CombineSequenceSeqs(ret);
    TrimSequenceByPlusNums(ret);
    return ret;
}

//all these assume items are in order by first element
public static List<List<int>> AddSequences(List<List<int>> origSeq, List<List<int>> addSeq) {
    List<List<int>> ret = new List<List<int>>();
    //add in items and clean up
    origSeq.AddRange(addSeq);
    //sort list by first item
    ret = origSeq.OrderBy(o => o[0]).ToList();
    DelSequenceDupes(ret);
    CombineSequenceNums(ret);
    CombineSequenceMergeNumsToSeqs(ret);
    CombineSequenceSeqs(ret);
    TrimSequenceByPlusNums(ret);
    return ret;
}

public static List<List<int>> DelSequenceDupes(List<List<int>> seq) {
    List<List<int>> ret = new List<List<int>>();
    List<int> prev = new List<int>();
    foreach (List<int> pair in seq) {
    if (prev.Count == 0) {
        ret.Add(pair);
        prev = pair;
    }
    else if (prev.Count != pair.Count || prev[0] != pair[0] || prev[1] != pair[1]) {
        ret.Add(pair);
        prev = pair;
    }
    }
    return ret;
}

public static List<List<int>> CombineSequenceNums(List<List<int>> seq) {
    List<List<int>> ret = new List<List<int>>();
    int conscount = 0;
    int previtem = -1;
    foreach (List<int> pair in seq) {
    if (pair.Count == 1) {
        if (conscount == 0) {
        previtem = pair[0];
        conscount++;
        }
        else {
        if (pair[0] == previtem + 1) {
            previtem = pair[0];
            conscount++;
        }
        //else deal with any sequences or not, and start over
        else {
            if (conscount < 3) {
            for (int i = conscount - 1; i >= 0; i--) {
                ret.Add(new List<int>() { previtem - i });
            }
            }
            //else its a sequence
            else {
            ret.Add(new List<int>() { previtem - (conscount - 1), previtem });
            }
            //start over on this number
            previtem = pair[0];
            conscount = 1;
        }
        }
    }
    else {
        //if on a sequence, see if conscount is more than 2
        if (conscount < 3) {
        for (int i = conscount - 1; i >= 0; i--) {
            ret.Add(new List<int>() { previtem - i });
        }
        }
        //else its a sequence
        else {
        ret.Add(new List<int>() { previtem - (conscount - 1), previtem });
        }
        //start over on bogus previtem
        previtem = -1;
        conscount = 0;
        //now add the sequence as is
        ret.Add(pair);
    }
    }
    //add any hanging numbers
    //if on a sequence, see if conscount is more than 2
    if (conscount < 3) {
    for (int i = conscount - 1; i >= 0; i--) {
        ret.Add(new List<int>() { previtem - i });
    }
    }
    //else its a sequence
    else {
    ret.Add(new List<int>() { previtem - (conscount - 1), previtem });
    }
    return ret;
}

public static List<List<int>> CombineSequenceSeqs(List<List<int>> seq) {
    List<List<int>> ret = new List<List<int>>();
    List<int> prevseq = new List<int>();
    foreach (List<int> pair in seq) {
    if (pair.Count == 1) {
        //add previous sequence if any
        if (prevseq.Count > 0) {
        ret.Add(prevseq);
        prevseq = new List<int>();
        }
        ret.Add(pair);
    }
    //else if a sequence
    else {
        if (pair[1] == -1) {
        //add previous sequence if any
        if (prevseq.Count > 0) {
            ret.Add(prevseq);
            prevseq = new List<int>();
        }
        ret.Add(pair);
        }
        else {
        if (prevseq.Count == 0) {
            prevseq = pair;
        }
        //if adjacent or any overlap, combine
        else {
            if (prevseq[1] + 1 >= pair[0]) {
            prevseq = new List<int>() { prevseq[0], Math.Max(pair[1], prevseq[1]) };
            }
            else {
            ret.Add(prevseq);
            prevseq = pair;
            }
        }
        }
    }
    }
    //add at end
    if (prevseq.Count > 0)
    ret.Add(prevseq);
    return ret;
}

public static List<List<int>> CombineSequenceMergeNumsToSeqs(List<List<int>> seq) {
    List<List<int>> ret = new List<List<int>>();
    int index = 0;
    while (index < seq.Count) {
    List<int> pair = seq[index];
    //if a number, add to ret
    if (pair.Count == 1 || (pair.Count == 2 && pair[1] == -1)) {
        ret.Add(pair);
        index++;
    }
    else {
        //if on a seq, look behind and ahead for numbers to gobble
        int lookback = 1;
        List<int> newpair = pair;
        bool go = true;
        while (go &&
           index > 0 &&
           index - lookback > -1) {
        if (seq[index - lookback].Count == 1 &&
            seq[index - lookback][0] == newpair[0] - 1) {
            //remove last item from ret
            ret.RemoveAt(ret.Count - 1);
            //modify newpair
            newpair[0] = newpair[0] - 1;
            lookback++;
        }
        else
            go = false;
        }
        //now look ahead, careful to get rid of item in the range already
        int lookahd = 1;
        go = true;
        while (go &&
           index < seq.Count + 1 &&
           index + lookahd < seq.Count) {
        if (seq[index + lookahd].Count == 1) {
            //if in range already
            if (seq[index + lookahd][0] <= newpair[1])
            lookahd++;
            else if (seq[index + lookahd][0] == newpair[1] + 1) {
            //modify newpair
            newpair[1] = newpair[1] + 1;
            lookahd++;
            }
            else
            go = false;
        }
        else
            go = false;
        }
        //add newpair to ret
        ret.Add(newpair);
        //jump past items done
        index = index + lookahd;
    }
    }
    return ret;
}

public static List<List<int>> TrimSequenceByPlusNums(List<List<int>> seq) {
    List<List<int>> ret = new List<List<int>>();
    //get sequence info
    int lowPlsNum;
    int highest = FindHighestInSeq(seq, out lowPlsNum);
    if (lowPlsNum != -1) {
    foreach (List<int> pair in seq) {
        if (pair.Count == 1) {
        if (pair[0] < lowPlsNum)
            ret.Add(pair);
        }
        else {
        if (pair[1] == -1) {
            if (pair[0] == lowPlsNum)
            ret.Add(pair);
        }
        else {
            if (pair[1] < lowPlsNum) {
            ret.Add(pair);
            }
            else if (pair[0] < lowPlsNum && pair[1] >= lowPlsNum)
            ret.Add(new List<int>() { pair[0], lowPlsNum - 1 });
        }
        }
    }
    }
    else
    ret = seq;
    return ret;
}

//assumes subtSeq has been cleaned so items are in order
public static List<List<int>> SubtractSequences(List<List<int>> origSeq, List<List<int>> subtSeq) {
    List<List<int>> ret = new List<List<int>>();
    if (subtSeq.Count > 0) {
    //go through origSeq and modify any items
    foreach (List<int> pair in origSeq) {
        //case 1 - just one number
        if (pair.Count == 1) {
        if (!IsPtInSequence(subtSeq, pair[0]))
            //add if not in subt sequence
            ret.Add(pair);
        }
        //case 2 - a sequence in orig
        else if (pair.Count == 2 && pair[1] != -1) {
        //must chop up based on items in subt
        List<List<int>> res = SubtractFromNonPlusSequence(pair, subtSeq);
        if (res.Count > 0)
            ret.AddRange(res);
        }
        //a number+
        else if (pair.Count == 2 && pair[1] == -1) {
        List<List<int>> res = SubtractFromPlusSequence(pair, subtSeq);
        if (res.Count > 0)
            ret.AddRange(res);
        }
    }
    }
    return ret;
}
//subtract a num+ by sequence
//origSeq  must have a -1 as second item
public static List<List<int>> SubtractFromPlusSequence(List<int> origSeq, List<List<int>> subtSeq) {
    List<List<int>> ret = new List<List<int>>();
    //handle by converting the num+ to a sequence plus a num+ if needed
    //find largest number in subtSeq
    int lowPlsNum;
    int largest = FindHighestInSeq(subtSeq, out lowPlsNum);
    List<int> tmpseq;
    //now make temp sequence
    if (lowPlsNum == -1) {
    //return original as its all before
    if (largest < origSeq[0]) {
        ret = new List<List<int>>() { origSeq };
    }
    else {
        //if overlap of 1
        if (largest - origSeq[0] == 1) {
        if (!IsPtInSequence(subtSeq, origSeq[0]))
            ret.Add(new List<int>() { origSeq[0] });
        }
        else if (largest - origSeq[0] == 2) {
        if (!IsPtInSequence(subtSeq, origSeq[0]))
            ret.Add(new List<int>() { origSeq[0] });
        if (!IsPtInSequence(subtSeq, origSeq[0] + 1))
            ret.Add(new List<int>() { origSeq[0] + 1 });
        }
        else {
        tmpseq = new List<int>() { origSeq[0], largest - 1 };
        ret.AddRange(SubtractFromNonPlusSequence(tmpseq, subtSeq));
        }
        //add a plus after all, since subtSeq did not have a +num in it
        ret.Add(new List<int>() { largest + 1, -1 });
    }
    }
    else {
    //its got a plus in it, just do before the subtract +
    if (lowPlsNum - origSeq[0] == 1) {
        ret.Add(new List<int>() { origSeq[0] });
    }
    else if (lowPlsNum - origSeq[0] == 2) {
        ret.Add(new List<int>() { origSeq[0] });
        ret.Add(new List<int>() { origSeq[0] + 1 });
    }
    else {
        tmpseq = new List<int>() { origSeq[0], lowPlsNum - 1 };
        ret.AddRange(SubtractFromNonPlusSequence(tmpseq, subtSeq));
    }
    //else return blank as it got wiped out
    }
    return ret;
}

//subtract a sequence (2 items) using another
public static List<List<int>> SubtractFromNonPlusSequence(List<int> origSeq, List<List<int>> subtSeq) {
    List<List<int>> ret = new List<List<int>>();
    //as we go along, curseq will be the term at hand to possibly chop
    List<int> curseq = origSeq;
    bool done = false;
    foreach (List<int> chopr in subtSeq) {
    if (!done) {
        //if chopping with one number
        if (chopr.Count == 1) {
        #region Chop with one
        //test if chop at all
        if (chopr[0] < curseq[0] || chopr[0] > curseq[1]) {
            ret.Add(curseq);
            done = true;
        }
        else {
            //handle left side of chop
            if (chopr[0] - curseq[0] == 1) {
            ret.Add(new List<int>() { curseq[0] });
            }
            else if (chopr[0] - curseq[0] == 2) {
            ret.Add(new List<int>() { curseq[0] });
            ret.Add(new List<int>() { curseq[0] + 1 });
            }
            else if (chopr[0] - curseq[0] > 2) {
            ret.Add(new List<int>() { curseq[0], chopr[0] - 1 });
            }
            //handle right side of chop
            if (curseq[1] - chopr[0] == 1) {
            ret.Add(new List<int>() { curseq[1] });
            done = true;
            }
            else if (curseq[1] - chopr[0] == 2) {
            ret.Add(new List<int>() { curseq[1] - 1 });
            ret.Add(new List<int>() { curseq[1] });
            done = true;
            }
            else if (curseq[1] - chopr[0] > 2) {
            curseq = new List<int>() { chopr[0] + 1, curseq[1] };
            }
        }
        }
        #endregion
        //now look at a chopper sequence
        else {
        //if a number +
        if (chopr[1] == -1) {
            #region Chop with one+
            //only 3 cases matter
            //if at or before start
            if (chopr[0] <= curseq[0]) {
            //stop
            done = true;
            }
            else if (chopr[0] > curseq[1]) {
            //do nothing
            }
            //if past start by 1
            else if (chopr[0] == curseq[0] + 1) {
            ret.Add(new List<int>() { curseq[0] });
            done = true;
            }
            //if past start by 2
            else if (chopr[0] == curseq[0] + 2) {
            ret.Add(new List<int>() { curseq[0] });
            ret.Add(new List<int>() { curseq[0] + 1 });
            //stop here because discard the rest
            done = true;
            }
            //if past start by more than 2
            else {
            ret.Add(new List<int>() { curseq[0], chopr[0] - 1 });
            done = true;
            }
        }
            #endregion
        //if a sequence
        else {
            #region Chop with seq
            //complete overlap
            if (curseq[0] >= chopr[0] && curseq[1] <= chopr[1]) {
            done = true;
            }
            //if we overlap chop start
            else if (chopr[1] == curseq[0]) {
            curseq = new List<int>() { curseq[0] + 1, curseq[1] };
            }
            //if we overlap chop end
            else if (chopr[0] == curseq[1]) {
            curseq = new List<int>() { curseq[0], curseq[1] - 1 };
            }
            //if we enclose chopper
            else if (chopr[0] > curseq[0] && chopr[1] < curseq[1]) {
            //handle left side
            if (chopr[0] - curseq[0] == 1) {
                ret.Add(new List<int>() { curseq[0] });
            }
            else if (chopr[0] - curseq[0] == 2) {
                ret.Add(new List<int>() { curseq[0] });
                ret.Add(new List<int>() { curseq[0] + 1 });
            }
            else {
                ret.Add(new List<int>() { curseq[0], chopr[0] - 1 });
            }
            //handle right side
            if (curseq[1] - chopr[1] == 1) {
                ret.Add(new List<int>() { curseq[1] });
                done = true;
            }
            else if (curseq[1] - chopr[1] == 2) {
                ret.Add(new List<int>() { curseq[1] - 1 });
                ret.Add(new List<int>() { curseq[1] });
                done = true;
            }
            else {
                curseq = new List<int>() { chopr[1] + 1, curseq[1] };
            }
            }
            //if we overlap past chop start
            else if (chopr[0] < curseq[0] && chopr[1] > curseq[0] && chopr[1] < curseq[1]) {
            //see if we leave nums or a sequence
            if (curseq[1] - chopr[1] == 1) {
                ret.Add(new List<int>() { curseq[1] });
                done = true;
            }
            else if (curseq[1] - chopr[1] == 2) {
                ret.Add(new List<int>() { curseq[1] - 1 });
                ret.Add(new List<int>() { curseq[1] });
                done = true;
            }
            else {
                curseq = new List<int>() { chopr[1] + 1, curseq[1] };
            }
            }
            //if we overlap before chop end
            else if (chopr[0] > curseq[0] && chopr[0] < curseq[1] && chopr[1] >= curseq[1]) {
            //see if we leave nums or a sequence
            if (chopr[0] - curseq[0] == 1) {
                ret.Add(new List<int>() { curseq[0] });
                done = true;
            }
            else if (chopr[0] - curseq[0] == 2) {
                ret.Add(new List<int>() { curseq[0] });
                ret.Add(new List<int>() { curseq[0] + 1 });
                done = true;
            }
            else {
                ret.Add(new List<int>() { curseq[0], chopr[0] - 1 });
                done = true;
            }
            }
        }
            #endregion
        }
    }
    }
    if (!done)
    ret.Add(curseq);
    return ret;
}

//find highest number in sequence, as well as lowest +num if an
//lowPlsNum is -1 if not found
public static int FindHighestInSeq(List<List<int>> seq, out int lowPlsNum) {
    //find largest number in subtSeq
    int ret = 0;
    //track lowest num+ if found in subtSeq
    lowPlsNum = -1;
    foreach (List<int> pair in seq) {
    if (pair.Count == 1) {
        if (pair[0] > ret)
        ret = pair[0];
    }
    else if (pair.Count == 2 && pair[1] != -1) {
        if (pair[1] > ret)
        ret = pair[1];
    }
    else if (pair.Count == 2 && pair[1] == -1) {
        if (lowPlsNum == -1)
        lowPlsNum = pair[0];
        if (pair[0] < lowPlsNum)
        lowPlsNum = pair[0];
    }
    }
    return ret;
}

public static bool IsPtInSequence(List<List<int>> seq, int ptnum) {
    bool ret = false;
    foreach (List<int> lst in seq) {
    if (lst.Count == 1) {
        if (lst[0] == ptnum)
        ret = true;
    }
    else if (lst.Count == 2) {
        //check if plus item
        if (lst[1] == -1) {
        if (ptnum >= lst[0])
            ret = true;
        }
        else if (ptnum >= lst[0] && ptnum <= lst[1])
        ret = true;
    }
    }
    return ret;
}

public static string RemoveChars(this string s) {
    string str = "";
    foreach (char c in s) {
        if (char.IsDigit(c) || c == '.' || c == ',' || c == '-') {
            str = str + c.ToString();
        }
    }
    return str;
}

//keep is list of single chars
public static string RemoveCharsExcept(this string s, string keep) {
    string str = "";
    foreach (char c in s) {
    if (char.IsDigit(c) || keep.Contains(c)) {
        str = str + c.ToString();
    }
    }
    return str;
}

/// <summary>
/// Returns the last few characters of the string with a length
/// specified by the given parameter. If the string's length is less than the 
/// given length the complete string is returned. If length is zero or 
/// less an empty string is returned
/// </summary>
/// <param name="s">the string to process</param>
/// <param name="length">Number of characters to return</param>
/// <returns></returns>
public static string Right(this string s, int length) {
    length = Math.Max(length, 0);
    if (s.Length > length) {
        return s.Substring(s.Length - length, length);
    }
    else {
        return s;
    }
}

/// <summary>
/// Returns the first few characters of the string with a length
/// specified by the given parameter. If the string's length is less than the 
/// given length the complete string is returned. If length is zero or 
/// less an empty string is returned
/// </summary>
/// <param name="s">the string to process</param>
/// <param name="length">Number of characters to return</param>
/// <returns></returns>
public static string Left(this string s, int length) {
    length = Math.Max(length, 0);

    if (s.Length > length) {
        return s.Substring(0, length);
    }
    else {
        return s;
    }
}
public static string StripLeft(this string s, int length) {
    length = Math.Max(length, 0);

    if (s.Length > length) {
        return s.Substring(length);
    }
    else {
        return "";
    }
}
public static string StripRight(this string s, int length) {
    length = Math.Max(length, 0);

    if (s.Length > length) {
        return s.Substring(0, s.Length - length);
    }
    else {
        return "";
    }
}

答案 2 :(得分:-1)

您提示您有三个不同的类,代表三种不同类型的范围。我希望你有一个聚合范围集合类?如果没有,请创建一个。这是一个伪代码算法,用于在将新集添加到现有集时执行的操作:

parser.add_argument("-a", "--action", nargs='*', action="store", help="do some action")
args = parser.parse_args()

if args.action is not None:
    if len(args.action) not in (0, 2):
        parser.error('Specify no or two actions')

    # action was specified but either there were two actions or no action
else:
    # action was not specified

注意:

  • 我只展示了如何处理单个数字。我把它作为练习留给你来扩展它来处理范围。它不应该难以理解。
  • 我还没有考虑过基本的防守,例如检查空值或空集。你会想要的。
  • 我已经做出了我认为对你的三个范围类所揭示的属性的合理假设。
  • 有些地方的天真实现会在遍历时从列表中删除元素时会出现运行时错误。您的实施需要考虑到这一点;这应该很容易。
  • 除了只允许增加无限范围(向正无穷大方向移动)之外,这对于负数是强有力的。例如,&#34; 10 - &#34; (意思是从10下降到负无穷大)不是有效范围。如果您需要该功能,则镜像无限范围代码相对简单。