从两个整数中获取范围

时间:2014-05-22 10:41:56

标签: c#

string num = db.SelectNums(id);
string[] numArr = num.Split('-').ToArray();

string num包含示例“48030-48039”;

string[] numArr将包含(48030,48039)。

现在我有两个元素,一个是高和低。我现在需要从48030到48039获得所有数字。问题是它必须是字符串,因为偶尔会有带前导零的电话号码。

这就是为什么我不能使用Enumerable.Range().ToArray()

有什么建议吗?预期结果应为48030,48031,48032,...,48039

8 个答案:

答案 0 :(得分:1)

这应该适用于你的领先零需求:

string num = db.SelectNums(id);
string[] split = num.Split('-');

long start = long.Parse(split[0]);
long end = long.Parse(split[1]);
bool includeLeadingZero = split[0].StartsWith("0");

List<string> results = new List<string>();

for(int i = start; i <= end; i++)
{
    string result = includeLeadingZero ? "0" : "";
    result += i.ToString();
    results.Add(result);
}

string[] arrayResults = results.ToArray();

有几点需要注意:

  • 假设您的输入将是由单个连字符分割的2个有效整数
  • 我给你一个字符串数组的结果,我个人希望最后使用List<int>
  • 如果第一个数字包含一个前导零,那么所有结果将包含一个前导零
  • 它使用long来满足更长的数字,请注意要解析的最大数字是9,223,372,036,854,775,807,您可以使用ulong

答案 1 :(得分:0)

你是说这个吗?

int[] nums = new int[numArr.Length];
for (int i = 0; i < numArr.Length; i++)
{
    nums[i] = Convert.ToInt32(numArr[i]);
}
Array.Sort(nums);
for (int n = nums[0]; n <= nums[nums.Length - 1]; n++)
{
    Console.WriteLine(n);
}

here link

答案 2 :(得分:0)

我期待你的字符串总是有两个整数,所以使用Parse代替TryParse

string[] strList = "48030-48039".Split('-').ToArray();

var lst = strList.Select(int.Parse).ToList();
var min = lst.OrderBy(l => l).FirstOrDefault();
var max = lst.OrderByDescending(l => l).FirstOrDefault();
var diff = max - min;

//adding 1 here otherwise 48039 will not be there
var rng = Enumerable.Range(min,diff+1);

如果您期望无效字符串

 var num = 0;
 var lst = (from s in strList where int.TryParse(s, out num) select num).ToList();

答案 3 :(得分:0)

这是一种方法:

    public static string[] RangeTest()
    {
        Boolean leadingZero = false;
        string num = "048030-48039"; //db.SelectNums(id);
        if (num.StartsWith("0"))
            leadingZero = true;

        int min = int.Parse(num.Split('-').Min());
        int count = int.Parse(num.Split('-').Max()) - min;
        if (leadingZero)
            return Enumerable.Range(min, count).Select(x => "0" + x.ToString()).ToArray();
        else
            return Enumerable.Range(min, count).Select(x => "" + x.ToString()).ToArray(); ;
    }

答案 4 :(得分:0)

您可以使用string.Format确保数字的格式为前导零。这将使该方法适用于任意数量的前导零。

private static string CreateRange(string num)
{
    var tokens = num.Split('-').Select(s => s.Trim()).ToArray();

    // use UInt64 to allow huge numbers
    var start = UInt64.Parse(tokens[0]);
    var end = UInt64.Parse(tokens[1]);

    // if your start number is '000123', this will create
    // a format string with 6 zeros ('000000')
    var format = new string('0', tokens[0].Length);

    // use StringBuilder to make GC happy.
    // (if only there was a Enumerable.Range<ulong> overload...)
    var sb = new StringBuilder();
    for (var i = start; i <= end; i++)
    {
        // format ensures that your numbers are padded properly
        sb.Append(i.ToString(format));
        sb.Append(", ");
    }

    // trim trailing comma after the last element
    if (sb.Length >= 2) sb.Length -= 2;

    return sb.ToString();
}

用法示例:

// prints 0000012, 0000013, 0000014
Console.WriteLine( CreateRange("0000012-0000014") );

答案 5 :(得分:0)

评论中提出了三个重要问题:

  1. 电话号码的数字足以超过Int32.MaxValue 转换为int是不可行的。

  2. 电话号码可以有前导零(对某些人来说可能是假的) 国际电话?)

  3. 理论上可能的数字范围超出了数组的最大大小(可能存在内存问题,我认为可能不会表示为string)< / p>

  4. 因此,您可能需要使用long而不是int,如果需要非常大的范围,我建议使用延迟执行。

    public static IEnumerable<string> EnumeratePhoneNumbers(string fromAndTo)
    {
        var split = fromAndTo.Split('-');
    
        return EnumeratePhoneNumbers(split[0], split[1]);
    }
    
    public static IEnumerable<string> EnumeratePhoneNumbers(string fromString, string toString)
    {
        long from = long.Parse(fromString);
        long to = long.Parse(toString);
    
        int totalNumberLength = fromString.Length;
    
        for (long phoneNumber = from; phoneNumber <= to; phoneNumber++)
        {
            yield return phoneNumber.ToString().PadLeft(totalNumberLength, '0');
        }
    }
    

    这假设填充的零已包含在下限fromString文本中。它将根据您的需要进行迭代并输出数字。如果您正在制作很多数字并且不需要用它们填充内存,或者如果您只需要前10或100,这可能很有用。例如:

    var first100Numbers = 
        EnumeratePhoneNumbers("0018155500-7018155510")
        .Take(100)
        .ToArray();
    

    通常该范围会产生 70亿结果,这些结果无法存储在数组中,并且可能会遇到内存问题(我甚至不确定它是否可以存储在字符串中);通过使用延迟执行,您只需创建所需的100个。

    如果您确实有一个小范围,您仍然可以根据需要将结果连接成一个字符串:

    string numberRanges = String.Join(", ", EnumeratePhoneNumbers("0018155500-0018155510"));
    

    当然,您可以将此数组创建放入您自己的帮助方法中:

    public static string GetPhoneNumbersListing(string fromAndTo)
    {
        return String.Join(", ", EnumeratePhoneNumbers("0018155500-0018155510"));
    }
    

    所以你的用法是:

    string numberRanges = GetPhoneNumbersListing("0018155500-0018155510");
    

答案 6 :(得分:0)

the answer by @Dan-o启发的完整解决方案:

<强>输入

Start:  48030
End:    48039
Digits:     6

预期字符串输出:

048030, 048031, 048032, 048033, 048034, 048035, 048036, 048037, 048038, 048039

<强>程序:

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

public class Program
{
    public static void Main()
    {
        int first  = 48030;
        int last   = 48039;
        int digits = 6;

        Console.WriteLine(CreateRange(first, last, digits));
    }

    public static string CreateRange(int first, int last, int numDigits)
    {
        string separator = ", ";

        var sb = new StringBuilder();
        sb.Append(first.ToString().PadLeft(numDigits, '0'));

        foreach (int num in Enumerable.Range(first + 1, last - first))
        {
            sb.Append(separator + num.ToString().PadLeft(numDigits, '0'));
        }

        return sb.ToString();
    }
}

答案 7 :(得分:-1)

For Each item In Enumerable.Range(min, count).ToArray()
  something = item.PadLeft(5, "0")
Next
相关问题