【问题标题】:Splitting numeric string into array将数字字符串拆分为数组
【发布时间】:2012-12-22 04:57:08
【问题描述】:

我有字符串 (10325710),我想将字符串拆分为一个数组。将字符串拆分为数组后,数组将为{1,0,3,2,5,7,1,0}。请注意,字符串中有两个1s 和两个0s。我不想拆分“1”和“0”。因此,我希望得到的数组是{10,3,2,5,7,10}

有什么建议吗?

我的 C# 代码:

string myNumber = "10325710";
string[] myArray = myNumber.Select(p => p.ToString()).ToArray();

【问题讨论】:

  • 你怎么知道数组中没有 32?还是只是没有零?
  • 我猜,字符串中只有值 1..10。不过,这应该明确说明。
  • 输出数组中允许的有效整数范围是多少?
  • ya...myNumber 中只有 1-10 个。

标签: c# arrays


【解决方案1】:

你可以很容易地手动完成。

int i = 0;

int len = 0;
for (int j = 0; j < s.Length; j++)
    if (s[j] != '0')
        len++;

int[] result = new int[len];
int index = 0;
while (i < s.Length)
{
    if (i < s.Length - 1 && int.Parse(s[i + 1].ToString()) == 0)
    {
        result[index++] = int.Parse(s[i].ToString()) * 10;
        i += 2;
    }
    else
    {
        result[index++] = int.Parse(s[i].ToString());
        i++;
    }
}

return result;

【讨论】:

  • 我喜欢这种方法,如果需求发生变化,将来更容易摆弄+1
  • 您确定此代码适用于这种情况吗?因为if (i &lt; myNumber.Length &amp;&amp; myNumber[i + 1] == 0) 行应该抛出OutOfRangeException
  • 它甚至无法编译,因为myNumber 似乎是字符串,而int.Parse(myNumber[i]) 不适用于字符。它也不会产生正确的结果。
  • 现在看来可以工作了。但是,撤消我的反对票,我会使用int.Parse(myNumber[i].ToString()) 而不是(int)Char.GetNumericValue(myNumber[i])
  • 我想知道,哪个会使用更少的内存。这是代码优化的问题,但我猜.ToString() 可能会实例化一个字符串实例,而GetNumericValue 不应该使用任何额外的内存,这就是我选择后者的原因。
【解决方案2】:
int[] nums = myNumber.Replace("10", "A")
                     .Select(c => Convert.ToInt32(c.ToString(), 16))
                     .ToArray();

基本上将“10”替换为“A”,然后将每个字符视为基数为 16 的数字。

【讨论】:

  • @Spook 不确定您所说的可扩展是什么意思。这个问题听起来他们只需要解析数字 1-10。此外,您通常会因为它错误而不是因为您不认为它是完美;)而否决答案
  • @ErenErsönmez 可维护在这里可能是一个更好的词。通常,您可以通过数千种方式解决问题,因此不能以是否解决问题来衡量其质量,而是以可维护性(易于修复或修改)的程度来衡量。假设 OP 也想解释 20s 和 30s。所有其他解决方案都可以修改(其中大部分很容易)以满足新的需求。这个必须从头开始重写(即使它很短)。跳出框框思考非常好,而且技巧确实很酷。但我认为,这不是解决问题的方式。
  • 那么如果 OP 想要解释 100s、1000s、电话号码……怎么办?所以你否决了一个完全有效的答案,因为它不满足一些甚至不存在的要求? :)
  • 这是给出有效结果的答案,但 IMO 本身无效。顺便说一句,出于好奇,我分析了 500k 长度字符串的解决方案。你的最快(400 毫秒)并且消耗 137M 的 RAM。 Dominic 需要 4.3s 和 222M,Ken 需要 5.1s 和 712M,而我的(修改后的) - 1.2s 和 61M。 ideone.com/GC1lTk
  • @Spook 我的头顶,您可能会通过在 .Select() 之前添加 .AsParallel().AsOrdered() 来获得 一些 改进。不过,我还没有考虑过并行化 String.Replace,这可能是一个有趣的练习。
【解决方案3】:

好吧,只是把一些正则表达式放在桌子上:

Regex.Split(myNumber, @"(?!^)(?=[1-9])");

【讨论】:

    【解决方案4】:

    声明:

    var myArray=Regex.Matches(myNumber, @"1?\d").Cast<Match>().Select(p => p.ToString()).ToArray();
    

    代码:

    var myNumber="98765432101032571001210345610789";
    var myMatches=Regex.Matches(myNumber, @"1?\d").Cast<Match>();
    var myArray=myMatches.Select(p => p.ToString()).ToArray();
    
    var whats_in_myArray="{ "+String.Join(", ", myArray)+" }";
    Debug.Print("{0}", whats_in_myArray);
    

    输出:

    { 9, 8, 7, 6, 5, 4, 3, 2, 10, 10, 3, 2, 5, 7, 10, 0, 12, 10, 3, 4, 5, 6, 10, 7, 8, 9 }
    

    【讨论】:

      猜你喜欢
      • 2016-04-01
      • 2012-02-22
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多