Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将列表转换为数字范围字符串_C#_String_Parsing - Fatal编程技术网

C# 将列表转换为数字范围字符串

C# 将列表转换为数字范围字符串,c#,string,parsing,C#,String,Parsing,这个问题与这个问题几乎相反: 如此给定 1,3,5,6,7,8,9,10,12: 我会说: 1,3,5-10,12 这是我的第一次尝试。这似乎有点骇人,可能是我写过的最糟糕的代码。你能建议一个更好的方法吗 static string numListToRangeStr(List<int> numList) { StringBuilder retString = new StringBuilder(); numList.Sort(); bool inRa

这个问题与这个问题几乎相反:

如此给定

1,3,5,6,7,8,9,10,12:
我会说:

1,3,5-10,12
这是我的第一次尝试。这似乎有点骇人,可能是我写过的最糟糕的代码。你能建议一个更好的方法吗

static string numListToRangeStr(List<int> numList)
{
    StringBuilder retString = new StringBuilder();
    numList.Sort();

    bool inRangeFind = false;
    int firstInRange = numList[0];
    int lastNumber = firstInRange;
    bool first = true;

    for (int i = 1; i < numList.Count; i++)
    {
        if (numList[i] == (lastNumber + 1))
        {
            inRangeFind = true;
        }
        else
        {             
            if (inRangeFind)
            {
                if (!first)
                {
                    retString.Append(",");
                }
                retString.Append(firstInRange);
                retString.Append("-");
            }
            else
            {
               if (!first)
                {
                    retString.Append(",");
                }
            }

            retString.Append(lastNumber);

            firstInRange = numList[i];
            inRangeFind = false;
            first = false;
        }

        lastNumber = numList[i];
    }


    if (inRangeFind)
    {
        if (!first)
        {
            retString.Append(",");
        }
        retString.Append(firstInRange);
        retString.Append("-");
    }
    else
    {
        if (!first)
        {
            retString.Append(",");
        }
    }
    retString.Append(lastNumber);

    return retString.ToString();
}
静态字符串numListToRangeStr(列表numList)
{
StringBuilder retString=新的StringBuilder();
numList.Sort();
bool inRangeFind=false;
int firstInRange=numList[0];
int lastNumber=firstInRange;
bool first=true;
for(int i=1;i
当某个东西有几个像这样的运动部件时,我认为将其分解成一些小的逻辑单元,然后将它们组合在一起是有帮助的。这些小逻辑单元甚至可以单独使用。下面的代码将问题分解为:

  • 将顺序数和非顺序数的异类集合转换为范围的异类集合(可能包括以相同数目开始和结束的“退化”范围)
  • “漂亮打印”这样的范围的一种方法:(x,y)打印为“x-y”;(x,x)打印为“x”
  • 一种在可枚举元素之间解释分隔符并将结果转换为字符串的方法
该计划是:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication37 {
  public static class Program {
    static void Main(string[] args) {
      var numList=new[] {1, 3, 5, 6, 7, 8, 9, 10, 12};
      Console.WriteLine(numListToPossiblyDegenerateRanges(numList).Select(r => PrettyRange(r)).Intersperse(","));
    }

    /// <summary>
    /// e.g. 1,3,5,6,7,8,9,10,12
    /// becomes
    /// (1,1),(3,3),(5,10),(12,12)
    /// </summary>
    public static IEnumerable<Tuple<int,int>> numListToPossiblyDegenerateRanges(IEnumerable<int> numList) {
      Tuple<int, int> currentRange=null;
      foreach(var num in numList) {
        if(currentRange==null) {
          currentRange=Tuple.Create(num, num);
        } else if(currentRange.Item2==num-1) {
          currentRange=Tuple.Create(currentRange.Item1, num);
        } else {
          yield return currentRange;
          currentRange=Tuple.Create(num, num);
        }
      }
      if(currentRange!=null) {
        yield return currentRange;
      }
    }

    /// <summary>
    /// e.g. (1,1) becomes "1"
    /// (1,3) becomes "1-3"
    /// </summary>
    /// <param name="range"></param>
    /// <returns></returns>
    public static string PrettyRange(Tuple<int,int> range) {
      if(range.Item1==range.Item2) {
        return range.Item1.ToString();
      }
      return string.Format("{0}-{1}", range.Item1, range.Item2);
    }

    public static string Intersperse(this IEnumerable<string> items, string interspersand) {
      var currentInterspersand="";
      var result=new StringBuilder();
      foreach(var item in items) {
        result.Append(currentInterspersand);
        result.Append(item);
        currentInterspersand=interspersand;
      }
      return result.ToString();
    }
  }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
命名空间控制台应用程序37{
公共静态类程序{
静态void Main(字符串[]参数){
var numList=new[]{1,3,5,6,7,8,9,10,12};
WriteLine(numListTopoPassiblyGeneratorAges(numList)。选择(r=>prettrange(r))。点缀(“,”);
}
/// 
///例如1,3,5,6,7,8,9,10,12
///变成
/// (1,1),(3,3),(5,10),(12,12)
/// 
公共静态IEnumerable NumlistTopoPassiblyGeneratorAges(IEnumerable numList){
元组currentRange=null;
foreach(numList中的var num){
如果(currentRange==null){
currentRange=Tuple.Create(num,num);
}else if(currentRange.Item2==num-1){
currentRange=Tuple.Create(currentRange.Item1,num);
}否则{
屈服返回电流范围;
currentRange=Tuple.Create(num,num);
}
}
如果(currentRange!=null){
屈服返回电流范围;
}
}
/// 
///例如(1,1)变为“1”
///(1,3)变为“1-3”
/// 
/// 
/// 
公共静态字符串预处理(元组范围){
if(range.Item1==range.Item2){
返回范围.Item1.ToString();
}
返回string.Format(“{0}-{1}”,range.Item1,range.Item2);
}
公共静态字符串穿插(此IEnumerable items,字符串穿插){
var和=”;
var result=新的StringBuilder();
foreach(项目中的var项目){
结果。追加(当前和);
结果:追加(项目);
currentInterspersand=interspersand;
}
返回result.ToString();
}
}
}

这应该可以很好地工作,但不是针对所有情况进行测试

        string s = "1,2,3,4,5,7,8,9,10,11,12,13";
        string[] ints = s.Split(',');
        StringBuilder result = new StringBuilder();

        int num, last = -1;
        bool dash = false;

        for (int ii = 0; ii < ints.Length; ii++)
        {
            num = Int32.Parse(ints[ii]);

            if (num - last > 1)
            {
                if (dash)
                {
                    result.Append(last);
                    dash = false;
                }
                if (result.Length > 0)
                {
                    result.Append(",");
                }
                result.Append(num);                    
            }
            else
            {
                if (dash == false)
                {
                    result.Append("-");
                    dash = true;
                }
            }

            last = num;

            if (dash && ii == ints.Length - 1)
            {
                result.Append(num);
            }
        }

        Console.WriteLine(result);
string s=“1,2,3,4,5,7,8,9,10,11,12,13”;
字符串[]int=s.Split(',');
StringBuilder结果=新建StringBuilder();
int num,last=-1;
布尔破折号=假;
对于(int ii=0;ii1)
{
如果(破折号)
{
结果。追加(最后一个);
破折号=假;
}
如果(result.Length>0)
{
结果。追加(“,”);
}
结果追加(num);
}
其他的
{
如果(破折号==假)
{
结果。追加(“-”);
破折号=真;
}
}
last=num;
if(虚线和ii==整数长度-1)
{
结果追加(num);
}
}
控制台写入线(结果);

这是一条旧线索,但这里有一个新答案。我将其构造为一个扩展方法。这将返回范围数组,其中每个“范围”要么是单个数字(
'13'
)要么是一对数字(
'5-12'
):


我必须解决同样的问题。正在寻找我的解决方案的替代方案,我认为这看起来更符合逻辑。所以分享吧。如果要对未排序的列表进行排序,请将第二个参数设置为true

public string ToRangeString(List<int> list, bool withSort) {
  list = list.Distinct().ToList();
  if(withSort) list.Sort();

  StringBuilder result = new StringBuilder();
  int temp;

  for (int i=0; i<list.Count(); i++) {
    temp = list[i];

    //add a number
    result.Append(list[i]);

    //skip number(s) between a range
    while(i<list.Count()-1 && list[i+1] == list[i]+1)
      i++;

    //add the range
    if(temp != list[i])
      result.Append("-").Append(list[i]);

    //add comma
    if(i != list.Count()-1)
      result.Append(", ");

  }
  return result.ToString();
}
public string-ToRangeString(列表,bool-with-sort){
list=list.Distinct().ToList();
if(使用排序)list.Sort();
StringBuilder结果=新建StringBuilder();
内部温度;

对于(inti=0;i,这里是RedFilter版本的稍微修改版本

它返回一个字符串而不是字符串数组,它删除0,如果在列表中,则在列表中只有一个值时避免异常

 public static string ToRanges(this List<int> ints)
    {
        ints.Remove(0); // Note: Remove this if you like to include the Value 0
        if (ints.Count < 1) return "";
        ints.Sort();
        var lng = ints.Count;
        if (lng == 1)
            return ints[0].ToString();

        var fromnums = new List<int>();
        var tonums = new List<int>();
        for (var i = 0 ; i < lng - 1 ; i++)
        {
            if (i == 0)
                fromnums.Add(ints[0]);
            if (ints[i + 1] > ints[i] + 1)
            {
                tonums.Add(ints[i]);
                fromnums.Add(ints[i + 1]);
            }
        }
        tonums.Add(ints[lng - 1]);


        string[] ranges = Enumerable.Range(0, tonums.Count).Select(
            i => fromnums[i].ToString() +
                (tonums[i] == fromnums[i] ? "" : "-" + tonums[i].ToString())
        ).ToArray();

        if (ranges.Length == 1)
            return ranges[0];
        else
            return String.Join(",", ranges);
    }
public string ToRangeString(List<int> list, bool withSort) {
  list = list.Distinct().ToList();
  if(withSort) list.Sort();

  StringBuilder result = new StringBuilder();
  int temp;

  for (int i=0; i<list.Count(); i++) {
    temp = list[i];

    //add a number
    result.Append(list[i]);

    //skip number(s) between a range
    while(i<list.Count()-1 && list[i+1] == list[i]+1)
      i++;

    //add the range
    if(temp != list[i])
      result.Append("-").Append(list[i]);

    //add comma
    if(i != list.Count()-1)
      result.Append(", ");

  }
  return result.ToString();
}
 public static string ToRanges(this List<int> ints)
    {
        ints.Remove(0); // Note: Remove this if you like to include the Value 0
        if (ints.Count < 1) return "";
        ints.Sort();
        var lng = ints.Count;
        if (lng == 1)
            return ints[0].ToString();

        var fromnums = new List<int>();
        var tonums = new List<int>();
        for (var i = 0 ; i < lng - 1 ; i++)
        {
            if (i == 0)
                fromnums.Add(ints[0]);
            if (ints[i + 1] > ints[i] + 1)
            {
                tonums.Add(ints[i]);
                fromnums.Add(ints[i + 1]);
            }
        }
        tonums.Add(ints[lng - 1]);


        string[] ranges = Enumerable.Range(0, tonums.Count).Select(
            i => fromnums[i].ToString() +
                (tonums[i] == fromnums[i] ? "" : "-" + tonums[i].ToString())
        ).ToArray();

        if (ranges.Length == 1)
            return ranges[0];
        else
            return String.Join(",", ranges);
    }
var numbers = new List<int>() { 1, 3, 5, 6, 7, 8, 9, 10, 12 };
var ranges = new List<string>();

if (numbers.Count == 0)
    return ranges;

numbers = numbers.Distinct().ToList();
numbers.Sort();

int start = numbers[0];
string range = start.ToString();

for (int i = 1; i <= numbers.Count; i++)
{
    if (i < numbers.Count && numbers[i] == numbers[i - 1] + 1)
    {
        range = $"{start} - {numbers[i]}";
        continue;
    }

    ranges.Add(range);

    if (i < numbers.Count)
    {
        start = numbers[i];
        range = start.ToString();
    }
}

var rangeString = string.Join(", ", ranges);  // Outputs: "1, 3, 5 - 10, 12"