不使用乘法 C# 将字符串转换为整数

cha*_*rhy 9 c# string int

有没有办法在不使用乘法的情况下将字符串转换为整数。int.Parse() 的实现也使用乘法。我还有其他类似的问题,您可以在其中手动将字符串转换为 int,但这也需要将数字乘以 10 为基数。这是我在其中一次采访中遇到的一个面试问题,我似乎找不到任何关于此的答案。

And*_*ing 12

如果你假设一个基数为 10 的数字系统并用位移(见这里)代替乘法,这可以是正整数的解决方案。

public int StringToInteger(string value)
{
    int number = 0;
    foreach (var character in value)
        number = (number << 1) + (number << 3) + (character - '0');

    return number;
}
Run Code Online (Sandbox Code Playgroud)

请参阅ideone上的示例

唯一的假设是,字符'0''9'位于字符集直接彼此相邻。使用 将数字字符转换为其整数值character - '0'

编辑:

对于负整数,此版本(请参阅此处)有效。

public static int StringToInteger(string value)
{
    bool negative = false;
    int i = 0;

    if (value[0] == '-')
    {
        negative = true;
        ++i;
    }

    int number = 0;
    for (; i < value.Length; ++i)
    {
        var character = value[i];
        number = (number << 1) + (number << 3) + (character - '0');
    }

    if (negative)
        number = -number;
    return number;
}
Run Code Online (Sandbox Code Playgroud)

通常,您应该考虑错误,例如空检查、其他非数字字符的问题等。


Lua*_*aan 6

这取决于。我们是在谈论乘法的逻辑运算,还是在硬件中实际是如何完成的?

例如,您可以将十六进制(或八进制,或任何其他基数为 2 的乘法器)字符串转换为“无需乘法”的整数。您可以逐个字符地进行并保持 oring ( |) 和bitshifting ( <<)。这避免了使用*运算符。

对十进制字符串做同样的事情比较棘手,但我们仍然有简单的加法。您可以使用带有附加功能的循环来做同样的事情。做起来很简单。或者你可以制作自己的“乘法表”——希望你在学校学会了如何乘法;你可以用电脑做同样的事情。当然,如果您使用的是十进制计算机(而不是二进制),您可以执行“bitshift”,就像使用早期的十六进制字符串一样。即使使用二进制计算机,您也可以使用一系列位移 -(a << 1) + (a << 3)a * 2 + a * 8 == a * 10. 小心负数。你可以想出很多技巧来使这变得有趣。

当然,这两者都只是变相的乘法。那是因为位置数字系统本质上是乘法的。这就是特定数字表示的工作方式。您可以通过简化来隐藏这一事实(例如,二进制数只需要0and 1,因此您可以有一个简单的条件而不是乘法 - 当然,您真正在做的仍然是乘法,只有两个可能的输入和两个可能的输入输出),但它总是在那里,潜伏着。<<与 相同* 2,即使执行操作的硬件可以更简单和/或更快。

要完全取消乘法,您需要避免使用位置系统。例如,罗马数字是累加的(请注意,实际的罗马数字没有用我们今天的紧凑化规则-四会IIII,不IV,这14可以在任何形式的像写XIIIIIIIIXIIXIIVVIIII等)。将这样的字符串转换为整数变得非常容易 - 只需一个字符一个字符,然后继续添加。如果字符是X,则加十。如果V,加五个。如果I,加一个。我希望你能明白为什么罗马数字能流行这么久;当您需要进行大量乘法和除法运算时,位置数字系统非常棒。如果您主要处理加法和减法,罗马数字效果很好,而且需要的教育也少得多(而且算盘比位置计算器更容易制作和使用!)。

对于这样的任务,面试官的实际期望有很多命中和遗漏。也许他们只是想看看你的思维过程。你接受技术细节(<<不是真正的乘法)吗?你知道数论和计算机科学吗?您是直接使用您的代码,还是要求澄清?您认为这是一个有趣的挑战,还是另一个与您的工作无关的荒谬无聊的面试问题?我们不可能告诉你面试官想要的答案。

但我希望我至少让你瞥见了可能的答案:)


nl-*_*l-x 5

考虑到这是一个面试问题,表现可能不是一个高优先级。为什么不只是:

private int StringToInt(string value)
{
    for (int i = int.MinValue; i <= int.MaxValue; i++)
        if (i.ToString() == value)
            return i;
    return 0; // All code paths must return a value.
}
Run Code Online (Sandbox Code Playgroud)

如果传入的字符串不是整数,该方法将抛出溢出异常。