如何提取数字的位置值?

时间:2017-12-18 17:45:08

标签: c# unity3d math multiplication

我正在使用C#在Unity游戏引擎中开发一个数学游戏,特别是一个可重用的组件来教授乘法的网格方法。例如,当给出数字34和13时,它应该生成3X3网格(用于乘数和被乘数位置值的标题列和行,以及乘数和被乘数中的位数2X2)。看起来像这样:

Multiplication grid

我的问题是我不知道提取数字的位置值的最佳方法(例如34 - > 30和4)。我只是想把它转换成一个字符串,根据它的索引将0添加到更高的位置值,并将其转换回int,但这似乎是一个糟糕的解决方案。有没有更好的方法呢?

注意:我几乎只处理正整数,但地方数量可能会有所不同。

感谢所有回答的人!认为发布我用所有回复构建的特定于Unity的解决方案可能会有所帮助:

List<int> GetPlaceValues(int num) {
    List<int> placeValues = new List<int>();
    while (num > 0) {
        placeValues.Add(num % 10);
        num /= 10;
    }
    for(int i = 0;i<placeValues.Count;i++) {
        placeValues[i] *= (int)Mathf.Pow(10, i);
    }
    placeValues.Reverse();
    return placeValues;
}

4 个答案:

答案 0 :(得分:2)

我的回答非常粗糙,并且可能会被具有更好数学技能的人提高:

void Main()
{
    GetMulGrid(34, 13).Dump();
}

int[,] GetMulGrid(int x, int y)
{
    int[] GetPlaceValues(int num)
    {
        var numDigits = (int)Math.Floor(Math.Log10(num) + 1);
        var digits = num.ToString().ToCharArray().Select(ch => Convert.ToInt32(ch.ToString())).ToArray();
        var multiplied =
            digits
            .Select((d, i) =>
            {
                if (i != (numDigits - 1) && d == 0) d = 1;
                return d * (int)Math.Pow(10, (numDigits - i) - 1);
            })
            .ToArray();
        return multiplied;
    }

    var xComponents = GetPlaceValues(x);
    var yComponents = GetPlaceValues(y);

    var arr = new int[xComponents.Length + 1, yComponents.Length + 1];

    for(var row = 0; row < yComponents.Length; row++)
    {
        for(var col = 0; col < xComponents.Length; col++)
        {
            arr[row + 1,col + 1] = xComponents[col] * yComponents[row];
            if (row == 0)
            {
                arr[0, col + 1] = xComponents[col];
            }
            if (col == 0)
            {
                arr[row + 1, 0] = yComponents[row];
            }
        }
    }

    return arr;
}

对于34 x 13的例子,它产生:

Basic grid

对于304 x 132,它产生:

enter image description here

它将此作为一个数组吐出,因此您如何使用和显示结果将取决于您。

答案 1 :(得分:2)

利用我们的号码系统的工作方式。这是一个基本的例子:

string test = "12034";
for (int i = 0; i < test.Length; ++i) {
    int digit = test[test.Length - i - 1] - '0';
    digit *= (int)Math.Pow(10, i);
    Console.WriteLine("digit = " + digit);
}

基本上,它从最右边的数字读取(假设输入是整数),并使用我们系统工作方式的方便位值来计算数字的含义。

test.Length - i - 1将最右边的视为0,并将其左侧的索引作为正数。

- '0'转换为&#39; 0&#39;的编码值到实际数字。

Play with the code

答案 2 :(得分:2)

也许你想要这样的东西(ideone):

int n = 76302;
int mul = 1;
int cnt = 0;
int res[10];

while(n) {
   res[cnt++] = (n % 10) * mul;
   mul*=10;
   cout << res[cnt-1] << " ";
   n = n / 10;
}

output 
2 0 300 6000 70000 

答案 3 :(得分:1)

对于两位数字,您可以使用模数

int n = 34;
int x = n % 10;   // 4
int y = n - x;    // 30