大数的乘法表示为数组?

时间:2016-04-04 14:45:02

标签: c# arrays methods

数字以相反的顺序存储在数组中。以下功能应该将两个数字lhsrhs相乘,并将产品存储在result中:

public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{        
     int length1 = Math.Max(lhs.Length, rhs.Length);
     for (int i = 0; i < length1; i++)
     {
        int[] PartialProduct = new int[result.Length];

        int length2 = Math.Min(lhs.Length, rhs.Length);
        for (int j = 0; j < length2; j++)
        {
            int multiplicand = (lhs.Length < rhs.Length) ? rhs[i] : lhs[i];
            int multiplier = (lhs.Length < rhs.Length) ? lhs[j] : rhs[j];

            int product = PartialProduct[i + j] + multiplicand * multiplier;

            PartialProduct[i + j] = product % 10;
            int carry = product / 10;

            PartialProduct[i + j + 1] = PartialProduct[i + j + 1] + carry;
        }
        SumDigitArrays(PartialProduct, result, result);
    }
}

但是,如果我乘以:

static void Main(string[] args)
{
    int[] n1 = { 1, 1 };
    int[] n2 = { 1, 1 };
    int[] result = new int[Math.Max(n1.Length, n2.Length) * 2 + 1];

    MultiplyDigitArrays(n1, n2, result);

    PrintArray(result);

    Console.WriteLine();
}

结果是:

00132

而不是预期的:

00121

我做错了什么?

对于MCVE:

public static void PrintArray(int[] Array)
{
    int length = Array.Length;
    for (int i = length - 1; i >= 0; i--)
    {
        Console.Write(Array[i]);

    }
}

public static void SumDigitArrays(int[] a, int[] b, int[] result)
{
    int length = Math.Max(a.Length, b.Length);
    for (int i = 0; i < length; i++)
    {
        int lhs = (i < a.Length) ? a[i] : 0;
        int rhs = (i < b.Length) ? b[i] : 0;

        int sum = result[i] + lhs + rhs;
        result[i] = sum % 10;

        int carry = sum / 10; 

        if (i + 1 < result.Length)
        {
            result[i + 1] = result[i + 1] + carry;
        }
    }
}

3 个答案:

答案 0 :(得分:4)

原因是因为调用background-position时使用的第三个参数应为空。而是向它提供结果变量,该变量包含除第一个之外的任何迭代的数据。

像这样实施你的方法:

background-repeat

答案 1 :(得分:3)

我不完全理解你正在执行的逻辑,但是

_

获得评估为

 int product = PartialProduct[i + j] + multiplicand * multiplier;

你打算做什么

int product = PartialProduct[i + j] + (multiplicand * multiplier);

因为这可以解释你的错误。

答案 2 :(得分:3)

除了给出的其他两个答案(这些是现场解决并解决您的问题),除非您有非常具体的需求,否则如果您需要增加非常大的话,我建议您选择BigInteger号。

根据您的具体需求(如果您的号码必须以一系列整数进出,这是存储任何数字的奇怪方式),您的Multiply可能会变为:< / p>

public static void MultiplyDigitArrays(int[] lhs, int[] rhs, int[] result)
{        
    var n1 = BigInteger.Parse(string.Join("", lhs));
    var n2 = BigInteger.Parse(string.Join("", rhs));
    var resultBi = BigInteger.Multiply(n1, n2);     
    Array.Clear(result, 0, result.Length);
    var stResult = resultBi.ToString().PadLeft(result.Length, '0');
    for(int i = 0; i < stResult.Length; i++)
    {
        result[(stResult.Length-1)-i] = int.Parse(stResult[i].ToString());
    }
}

请注意,此函数的负担实际上是来回转换整数数组,因为整数数组是存储数字的奇怪格式。

如果直接使用字符串(或BigInteger s),则不需要此功能。例如,如果使用包含数字的字符串,则可能会变为:

public static string MultiplyBigNumbers(string lhs, string rhs)
{        
    var n1 = BigInteger.Parse(lhs);
    var n2 = BigInteger.Parse(rhs);
    return BigInteger.Multiply(n1, n2).ToString();      
}

只需拨打电话:MultiplyBigNumbers("3242", "42349");

然后,我建议只使用BigInteger一直向下,并在需要存储时将其转换(byte数组更有意义,并且您可以使用ToByteArray())或显示(可以通过ToString()来电轻松完成)

请注意,为结果传递数组也很奇怪(无论如何都是.NET),因为您不需要原始值。你最好返回一个数组并计算函数本身所需的长度,而不是让调用者弄清楚它。