【问题标题】:multiplication of two numbers两个数的乘法
【发布时间】:2012-02-12 12:14:18
【问题描述】:

几天前,我接受了高通的采访。我有点坚持一个问题,你这个问题看起来很简单,但我和面试官都不满意我的回答,如果有人能提供任何好的解决方案的话。

问题是:

不使用任何循环和加法,当然也不使用乘法和除法。

我的回答是:递归

他在非常低的水平上说了其他任何事情。

我想到的真正想法是位移,但位移只会将数字乘以 2 的幂,而对于其他数字,我们最终必须进行加法。

例如:10 * 7 可以做为:(二进制的 7 ~~ 111) 10

但不允许再次添加。

关于这个问题的任何想法。

【问题讨论】:

  • 呵呵当然不是...没有乘法没有“*”也没有除法。
  • - 运算符是否允许?您应该更新您的问题以反映这些限制。
  • 说真的,高通应该只投资一个好的*运营商。但这解释了很多。
  • 这和让别人做一个没有鸡蛋的煎蛋卷差不多。
  • 如果允许对数和减法,请查看我的答案。而在现实中,这两种操作最终都会执行加法,但您自己并不是在执行加法或乘法

标签: c multiplication


【解决方案1】:

这是一个仅使用查找、加法和移位的解决方案。查找不需要乘法,因为它是指向另一个数组的指针数组 - 因此需要添加才能找到正确的数组。然后使用第二个值可以重复指针运算并得到查找结果。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
  /* Note:As this is an array of pointers to an array of values, addition is
     only required for the lookup.

     i.e. 

     First part: lookup + a value -> A pointer to an array
     Second part - Add a value to the pointer to above pointer to get the value
  */
  unsigned char lookup[16][16] = {
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
    { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 },
    { 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45 },
    { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 },
    { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75 },
    { 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90 },
    { 0, 7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98, 105 },
    { 0, 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120 },
    { 0, 9, 18, 27, 36, 45, 54, 63, 72, 81, 90, 99, 108, 117, 126, 135 },
    { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 },
    { 0, 11, 22, 33, 44, 55, 66, 77, 88, 99, 110, 121, 132, 143, 154, 165 },
    { 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180 },
    { 0, 13, 26, 39, 52, 65, 78, 91, 104, 117, 130, 143, 156, 169, 182, 195 },
    { 0, 14, 28, 42, 56, 70, 84, 98, 112, 126, 140, 154, 168, 182, 196, 210 },
    { 0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225 }
  };
  unsigned short answer, mult;
  unsigned char x, y, a, b;

  x = (unsigned char)atoi(argv[1]);
  y = (unsigned char)atoi(argv[2]);
  printf("Multiple %d by %d\n", x, y);

  answer = 0;
  /* First nibble of x, First nibble of y */
  a = x & 0xf;
  b = y & 0xf;
  mult = lookup[a][b];
  answer += mult;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* First nibble of x, Second nibble of y */
  a = x & 0xf;
  b = (y & 0xf0) >> 4;
  mult = lookup[a][b];
  answer += mult << 4;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* Second nibble of x, First nibble of y */
  a = (x & 0xf0) >> 4;
  b = y & 0xf;
  mult = lookup[a][b];
  answer += mult << 4;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  /* Second nibble of x, Second nibble of y */
  a = (x & 0xf0) >> 4;
  b = (y & 0xf0) >> 4;
  mult = lookup[a][b];
  answer += mult << 8;
  printf("Looking up %d, %d get %d - Answer so far %d\n", a, b, mult, answer);

  return 0;
} 

【讨论】:

    【解决方案2】:

    也许您可以递归地添加,使用按位运算代替加法运算符。见:Adding Two Numbers With Bitwise and Shift Operators

    【讨论】:

      【解决方案3】:

      您可以通过首先实现加法然后基于加法的乘法来分离您的问题。

      此外,使用 C 位运算符在门级实现它们在处理器上所做的事情:

      http://en.wikipedia.org/wiki/Full_adder

      然后对于乘法,使用您实现的加法,使用 goto 语句和标签,因此不会使用循环语句(forwhiledo 迭代语句)。

      【讨论】:

        【解决方案4】:

        不使用加法的俄罗斯农民乘法呢?有没有简单的方法(几行,没有循环)只使用 AND、OR、XOR 和 NOT 来模拟加法?

        【讨论】:

          【解决方案5】:

          您可以通过位运算符实现加法。但是,如果你想避免循环,你应该写很多代码。 (我以前用没有算术运算符的方式实现乘法,但是我使用循环,将索引移动到零。如果它可以帮助你,告诉我,我会搜索文件)

          【讨论】:

            【解决方案6】:

            您可以改用对数和减法。

            log(a*b) = log(a) + log(b)
            a+b = -(-a-b)
            exp(log(a)) = a

            round(exp(-(-log(a)-log(b))))
            

            【讨论】:

              【解决方案7】:

              乘法表怎么样?

              【讨论】:

              • 从技术上讲,这是最简单、最快的实现,但会消耗内存。例如,4bit x 4bit 最多可以有 8 位数据输出,可以通过多路复用器实现!然而,这种方法对大量数据不利。仍然解决了问题-_-
              • 你能举例说明你在说什么吗..multiplication tables
              • 好吧,假设你想乘以 3*8。 3-> 0011; 4->0100。它们的乘法是 8 位(必需)是 12,即 00001100。构建一个 ROM 或多路复用器,它以 8 位作为输入(2 个数字的 4 位)。 ROM 只需查看内部表即可快速搜索输入并生成输出。 IE;这些表包含的数据使得 00110100(3,4) 映射到 00001100(12) 等等,以获取 4 位数字的可能组合列表。
              • 其实“Ed Heal”刚刚发布了一个具有相同想法的C程序:)
              【解决方案8】:

              问题:两个数字相乘,不使用任何循环和加法,当然也没有乘法和除法。

              乘法是根据加法定义的。在乘法的实现中不可能不找到加法。

              没有循环/递归就不能相乘任意精度的数字。

              两个固定位长的乘法可以通过查表来实现。问题是桌子的大小。生成表需要加法。

              答案是:做不到。

              【讨论】:

                猜你喜欢
                • 2016-04-14
                • 2015-07-03
                • 2015-10-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-01-28
                • 2015-03-09
                • 1970-01-01
                相关资源
                最近更新 更多