【问题标题】:Split string of numbers into digits and send to array将一串数字拆分为数字并发送到数组
【发布时间】:2018-12-05 21:00:29
【问题描述】:

我想拆分一个 40 位数字并将每个数字发送到一个称为数字的数组中。 ToArray 不起作用,因为它无法从 char 转换为 int。我也不认为斯普利特?我被难住了

edit:这些是指令:创建一个类 HugeInteger,它使用一个 40 元素的数字数组来存储每个 40 位大的整数。提供方法 Input、ToString、Add 和 Subtract。对于 HugeInteger 对象的比较,提供以下方法:IsEqualTo、IsNotEqualTo、IsGreaterThan、IsLessThan、IsGreaterThanOrEqualTo 和 IsLessThanOrEqualTo。如果两个 HugeInteger 对象之间的关系成立,这些方法中的每一个都返回 true,如果关系不成立,则返回 false。提供方法 IsZero。在 Input 方法中,使用字符串方法 ToCharArray 将输入字符串转换为字符数组,然后遍历这些字符来创建你的 HugeInteger。

【问题讨论】:

  • 您的“数字”是什么数据类型,我假设您要将“数字”转换为 int 类型的数组?
  • 您需要在每个字符上使用int.Parseint.TryParse
  • int[] digits = "12345".Where(char.IsNumber).Select(c => int.Parse(c.ToString())).ToArray();
  • 您的号码是否存储为stringint? double?
  • @Captain Wibble 我想我将使用一个字符串,是的,数组将是 int

标签: c# arrays


【解决方案1】:
string digits = "8957853759876839473454789595495735984339";
int[] array = digits.Select(x => (int)char.GetNumericValue(x)).ToArray();

或者

int[] array = digits.Select(x => x - 48).ToArray();

正如@Haldo 要求解释为什么这个应该起作用,这是因为 char 可以隐式转换为 int。 Live Demo

如果你想避免在有字符不能被解析为数字的情况下出现异常,你可以忽略它们:

int[] array = digits.Where(x => char.IsNumber(x)).Select(x => x - 48).ToArray();

【讨论】:

  • 为什么不直接使用Char.GetNumericValue(x)
  • 请注意,如果您怀疑某个字符不是数字并且您不想抛出异常,请在digits.Select 之间添加.Where(char.IsNumber)。跨度>
  • @AshkanMobayenKhiabani 是的,我知道...但通常我们期望或假设为真的情况并非总是如此。如果他们想避免可能的异常,只是给 OP 的一个注释。
  • @AshkanMobayenKhiabani 谢谢!我并不怀疑它是否有效,我只是好奇为什么。我调查了一下,这是因为每个 char 在内部都表示为一个整数。 '0' 的值为 48,因此减法自动转换为 int,例如 '9' - '0' = 57 - 48 = 9。我想!
  • @hadlo 欢迎您。由于 char.MinValue 到 char.MaxValue 都在 int 范围内,因此为其设置了隐式转换,但相反的情况并非如此,将 byte 转换为 int 也是如此,...
【解决方案2】:

您可以使用Select扩展方法将字符转换为整数:

int[] result = str.Select(x => int.Parse(x.ToString()))
                  .ToArray();

或假设可能存在无效字符:

int[] result = str.Where(char.IsDigit)
                  .Select(x => int.Parse(x.ToString()))
                  .ToArray();

【讨论】:

    【解决方案3】:

    要处理大量数字,最好的方法是将整数字符串转换为字节数组。因此代码将十进制数转换为二进制 byte[] 数组。是使用学校教的方法,使用长除法将十进制转换为十六进制。

    我使用 0 到 2^24 之间的每个数字彻底测试了代码。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication89
    {
        class Program
        {
            static void Main(string[] args)
            {
    
                string digits = "8957853759876839473454789595495735984339";
                List<byte> results = Binary.GetBytes(digits);
                //test code
                //for (int i = 0; i < (Math.Pow(2,24)); i++)
                //{
                //    string digits = i.ToString();
                //    Console.WriteLine(i);
                //    List<byte> results = Binary.GetBytes(digits);
                //    long value = results.Select((x, j) => x << (j * 8)).Sum();
                //    if (i != value)
                //    {
                //        int a = 3;
                //    }
                //}
            }
    
    
        }
        public class Binary
        {
            public static List<byte> GetBytes(string input)
            {
                List<byte> results = new List<byte>();
                string divisorStr = input;
    
    
                int nibbleCount = 0;
    
    
                while (divisorStr.Length != 0)
                {
                    int number = 0;
                    string quotentStr = "";
                    byte carry = 0;
    
                    //divide a string by 16 to get remainders
                    while (divisorStr.Length != 0)
                    {
                        number = (carry * 10) + int.Parse(divisorStr.Substring(0, 1));
                        divisorStr = divisorStr.Substring(1);
                        if (divisorStr.Length == 0) exit = true;
    
                        int digit = number / 16;
                        if (quotentStr != "" | (digit != 0))
                        {
                            quotentStr += digit.ToString();
                        }
                        carry = (byte)(number % 16);
                    }
                    ///combine the remainders together into an array of bytes
                    if (nibbleCount % 2 == 0)
                    {
                        results.Add(carry);
                    }
                    else
                    {
                        results[results.Count - 1] |= (byte)(carry << 4);
                    }
                    divisorStr = quotentStr;
                    nibbleCount++;
                }
                return results;
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      既然您只想将它​​放入一个char 数组中,为什么不直接在int 上调用.ToString(),然后再调用.ToCharArray()

      int nums = 123456789;
      
      char[] numss = nums.ToString().ToCharArray();
      
      foreach(char n in numss) {
          Console.Write(string.Format("{0} ", n));
      }
      // 1 2 3 4 5 6 7 8 9... 
      

      既然我误读了这个问题,而且每个人都在使用Select 扩展,为什么不直接使用一个简单的for 循环并将它们转换为int

      string nums = "12345";
      int [] digits = new int[nums.Length];
      
      for(int i = 0; i < nums.Length; i++) {
          digits[i] = Convert.ToInt32(Char.GetNumericValue(nums[i]));
      }
      
      foreach(int n in digits) {
          Console.Write(string.Format("{0} ", n));
      }
      // 1 2 3 4 5
      

      【讨论】:

      • OP 想要一个 int 数组,而不是 char 数组
      • OP 以一串数字开头,并希望将其转换为整数数组。
      • 已修复。没有看到问题标题中的结果数组的实际类型。
      猜你喜欢
      • 2012-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多