Divide a number by 3 without using *, /, +, -, % operators
在不使用
号码可以是有符号的或无符号的。
这是一个执行所需操作的简单函数。但它需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // replaces the + operator int add(int x, int y) { while (x) { int t = (x & y) << 1; y ^= x; x = t; } return y; } int divideby3(int num) { int sum = 0; while (num > 3) { sum = add(num >> 2, sum); num = add(num >> 2, num & 3); } if (num == 3) sum = add(sum, 1); return sum; } |
正如吉姆所说,这是可行的,因为:
n = 4 * a + b n / 3 = a + (a + b) / 3 因此,
sum += a 、n = a + b 和迭代当
a == 0 (n < 4) 时,sum += floor(n / 3); 即1、if n == 3, else 0 时
愚蠢的条件需要一个愚蠢的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> #include <stdlib.h> int main() { FILE * fp=fopen("temp.dat","w+b"); int number=12346; int divisor=3; char * buf = calloc(number,1); fwrite(buf,number,1,fp); rewind(fp); int result=fread(buf,divisor,number,fp); printf("%d / %d = %d", number, divisor, result); free(buf); fclose(fp); return 0; } |
如果还需要小数部分,只需声明
解释其工作原理
如果写入30个字节,然后以3为单位读取文件,则得到10个"单位"。30/3=10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
您可以使用(依赖平台)内联程序集,例如,用于x86:(也适用于负数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <stdio.h> int main() { int dividend = -42, divisor = 5, quotient, remainder; __asm__ ("cdq; idivl %%ebx;" :"=a" (quotient),"=d" (remainder) :"a" (dividend),"b" (divisor) : ); printf("%i / %i = %i, remainder: %i ", dividend, divisor, quotient, remainder); return 0; } |
使用ITOA转换为基3字符串。放下最后一个Trit,然后转换回Base 10。
1 2 3 4 5 6 7 8 9 10 11 | // Note: itoa is non-standard but actual implementations // don't seem to handle negative when base != 10. int div3(int i) { char str[42]; sprintf(str,"%d", INT_MIN); // Put minus sign at str[0] if (i>0) // Remove sign if positive str[0] = ' '; itoa(abs(i), &str[1], 3); // Put ternary absolute value starting at str[1] str[strlen(&str[1])] = '\0'; // Drop last digit return strtol(str, NULL, 3); // Read back result } |
(注:请参阅下面的编辑2以获得更好的版本!)
这并不像听起来那么复杂,因为您说过"不使用[..]
1 2 3 4 5 6 7 8 9 10 |
那么就说
1 2 3 4 5 6 7 8 9 | unsigned inc(unsigned x) { for (unsigned mask = 1; mask; mask <<= 1) { if (mask & x) x &= ~mask; else return x & mask; } return 0; // overflow (note that both x and mask are 0 here) } |
编辑2:速度稍快的版本,不使用包含
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | unsigned add(char const zero[], unsigned const x, unsigned const y) { // this exploits that &foo[bar] == foo+bar if foo is of type char* return (int)(uintptr_t)(&((&zero[x])[y])); } unsigned div_by(unsigned const x, unsigned const by) { unsigned floor = 0; for (unsigned cmp = 0, r = 0; cmp <= x;) { cmp = add(0,cmp,by); floor = r; r = add(0,r,1); } return floor; } |
我们使用
fwiw,您可以使用类似的技巧轻松实现乘法函数,使用andreyt提出的
1 2 3 4 5 | int mul(int const x, int const y) { return sizeof(struct { char const ignore[y]; }[x]); } |
它是可能的setun很容易在计算机上。
西安市的两个整数除以3,1右移位的城市广场。
在我不确定它是否是可能的严格实施的一个C编译器的协调通过一个这样的平台,但。我们可能会有两个伸展的游戏规则(一位样解释,"至少8位"AA"capable控股(至少从两个integers + 127 128"。
由于它的从Oracle,如何查找表的前一部calculated回答。:D
我的解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public static int div_by_3(long a) { a <<= 30; for(int i = 2; i <= 32 ; i <<= 1) { a = add(a, a >> i); } return (int) (a >> 32); } public static long add(long a, long b) { long carry = (a & b) << 1; long sum = (a ^ b); return carry == 0 ? sum : add(carry, sum); } |
首先,注意
1 | 1/3 = 1/4 + 1/16 + 1/64 + ... |
现在,剩下的很简单!
1 2 3 4 | a/3 = a * 1/3 a/3 = a * (1/4 + 1/16 + 1/64 + ...) a/3 = a/4 + a/16 + 1/64 + ... a/3 = a >> 2 + a >> 4 + a >> 6 + ... |
现在我们要做的就是把这些位移值加起来!哎呀!但是我们不能添加,因此我们必须使用位运算符编写一个添加函数!如果您熟悉位智能运算符,我的解决方案应该看起来相当简单…不过,万一你没有,我最后会举个例子。
另一件事要注意的是,我第一次左移30!这是为了确保分数不会四舍五入。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 11 + 6 1011 + 0110 sum = 1011 ^ 0110 = 1101 carry = (1011 & 0110) << 1 = 0010 << 1 = 0100 Now you recurse! 1101 + 0100 sum = 1101 ^ 0100 = 1001 carry = (1101 & 0100) << 1 = 0100 << 1 = 1000 Again! 1001 + 1000 sum = 1001 ^ 1000 = 0001 carry = (1001 & 1000) << 1 = 1000 << 1 = 10000 One last time! 0001 + 10000 sum = 0001 ^ 10000 = 10001 = 17 carry = (0001 & 10000) << 1 = 0 Done! |
你小时候学的只是简单的加法!
1 2 3 4 5 | 111 1011 +0110 ----- 10001 |
此实现失败,因为我们无法添加公式的所有项:
1 2 | a / 3 = a/4 + a/4^2 + a/4^3 + ... + a/4^i + ... = f(a, i) + a * 1/3 * 1/4^i f(a, i) = a/4 + a/4^2 + ... + a/4^i |
假设EDOCX1的reslut(39)=x,然后是
要将32位数字除以3,可以将其乘以
现在剩下要做的就是用位操作和移位实现乘法…
而另一个解决方案。我们应该采取行动(包括负全ints ints)"除非我个int值,这将需要两个手腕硬编码作为一个例外。这是basically分市subtraction但只使用位操作人员(shifts,异或,&;鸭补)。因为它的速度快,subtracts 3×(缓变的权力(2)。在# C,它在executes 444个divideby3要求每millisecond(2.2秒为1000000 divides),所以不horrendously慢,但没有在近AA房作为一个简单的X / 3。城市的对比,很好的解决方案coodey冰约5小时禁食,这一个。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public static int DivideBy3(int a) { bool negative = a < 0; if (negative) a = Negate(a); int result; int sub = 3 << 29; int threes = 1 << 29; result = 0; while (threes > 0) { if (a >= sub) { a = Add(a, Negate(sub)); result = Add(result, threes); } sub >>= 1; threes >>= 1; } if (negative) result = Negate(result); return result; } public static int Negate(int a) { return Add(~a, 1); } public static int Add(int a, int b) { int x = 0; x = a ^ b; while ((a & b) != 0) { b = (a & b) << 1; a = x; x = a ^ b; } return x; } |
这是# C,因为那就是仇恨得心应手,但差异应该是从C小调。
它的真的很长很容易。
1 2 3 4 5 6 7 | if (number == 0) return 0; if (number == 1) return 0; if (number == 2) return 0; if (number == 3) return 1; if (number == 4) return 1; if (number == 5) return 1; if (number == 6) return 2; |
(当然有一些omitted报计划部的缘故brevity)。如果计划得到了这部全typlng疲倦了,我生气,他或她可以写一个程序,它的两个Generate他。发生在两个感知某运营商
使用的计数器是一个基本的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | int DivBy3(int num) { int result = 0; int counter = 0; while (1) { if (num == counter) //Modulus 0 return result; counter = abs(~counter); //++counter if (num == counter) //Modulus 1 return result; counter = abs(~counter); //++counter if (num == counter) //Modulus 2 return result; counter = abs(~counter); //++counter result = abs(~result); //++result } } |
它也很容易perform a模两种功能,检查的评论。
这是一个经典的分割算法在基地2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <stdio.h> #include <stdint.h> int main() { uint32_t mod3[6] = { 0,1,2,0,1,2 }; uint32_t x = 1234567; // number to divide, and remainder at the end uint32_t y = 0; // result int bit = 31; // current bit printf("X=%u X/3=%u ",x,x/3); // the '/3' is for testing while (bit>0) { printf("BIT=%d X=%u Y=%u ",bit,x,y); // decrement bit int h = 1; while (1) { bit ^= h; if ( bit&h ) h <<= 1; else break; } uint32_t r = x>>bit; // current remainder in 0..5 x ^= r<<bit; // remove R bits from X if (r >= 3) y |= 1<<bit; // new output bit x |= mod3[r]<<bit; // new remainder inserted in X } printf("Y=%u ",y); } |
用pascal编写程序,并使用
因为这个问题被标记为C,所以您可以用Pascal编写一个函数并从C程序中调用它;这样做的方法是特定于系统的。
但这里有一个在我的Ubuntu系统上运行的例子,安装了免费的pascal
1 2 3 4 5 6 7 8 9 | unit Divide_By_3; interface function div_by_3(n: integer): integer; cdecl; export; implementation function div_by_3(n: integer): integer; cdecl; begin div_by_3 := n div 3; end; end. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
建造:
1 | fpc divide_by_3.pas && gcc divide_by_3.o main.c -o main |
样本执行:
1 2 3 | $ ./main Enter a number: 100 100 / 3 = 33 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int div3(int x) { int reminder = abs(x); int result = 0; while(reminder >= 3) { result++; reminder--; reminder--; reminder--; } return result; } |
这应该对任何因子的工作,不只是三。目前只有在unsigned展,但它不应该是两个签名,难。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #include <stdio.h> unsigned sub(unsigned two, unsigned one); unsigned bitdiv(unsigned top, unsigned bot); unsigned sub(unsigned two, unsigned one) { unsigned bor; bor = one; do { one = ~two & bor; two ^= bor; bor = one<<1; } while (one); return two; } unsigned bitdiv(unsigned top, unsigned bot) { unsigned result, shift; if (!bot || top < bot) return 0; for(shift=1;top >= (bot<<=1); shift++) {;} bot >>= 1; for (result=0; shift--; bot >>= 1 ) { result <<=1; if (top >= bot) { top = sub(top,bot); result |= 1; } } return result; } int main(void) { unsigned arg,val; for (arg=2; arg < 40; arg++) { val = bitdiv(arg,3); printf("Arg=%u Val=%u ", arg, val); } return 0; } |
没有交叉检查,如果这个答案已经发表的冰。如果程序需要两个扩展浮数,数可以倍增10×号城市大学精密需要下面的代码,然后可以应用了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <stdio.h> int main() { int aNumber = 500; int gResult = 0; int aLoop = 0; int i = 0; for(i = 0; i < aNumber; i++) { if(aLoop == 3) { gResult++; aLoop = 0; } aLoop++; } printf("Reulst of %d / 3 = %d", aNumber, gResult); return 0; } |
使用PHP数学:在公元前
1 2 3 4 | <?php $a = 12345; $b = bcdiv($a, 3); ?> |
(它的MySQL的访谈从Oracle)
1 | > SELECT 12345 DIV 3; |
Pascal:
1 2 |
x86 64装配语言:
1 2 3 4 | mov r8, 3 xor rdx, rdx mov rax, 12345 idiv r8 |
它是将两个使用欺骗的
例如,在javacript,你能做的
第一,我在用VC来的IP。
1 2 3 4 5 6 | irb(main):101:0> div3 = -> n { s = '%0' + n.to_s + 's'; (s % '').gsub(' ', ' ').size } => #<Proc:0x0000000205ae90@(irb):101 (lambda)> irb(main):102:0> div3[12] => 4 irb(main):103:0> div3[666] => 222 |
编辑:对不起,我没有注意到你的
下面的脚本generates C程序,用solves问题没有所谓的运营商
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/usr/bin/env python3 print('''#include <stdint.h> #include <stdio.h> const int32_t div_by_3(const int32_t input) { ''') for i in range(-2**31, 2**31): print(' if(input == %d) return %d;' % (i, i / 3)) print(r''' return 42; // impossible } int main() { const int32_t number = 8; printf("%d / 3 = %d ", number, div_by_3(number)); } ''') |
使用黑客的喜悦幻数计算器
1 2 3 4 | int divideByThree(int num) { return (fma(num, 1431655766, 0) >> 32); } |
其中,fma是在
我认为正确的答案是:
为什么不使用基本运算符执行基本操作?
这种方法(c)怎么样?
1 2 3 4 5 6 7 8 9 | private int dividedBy3(int n) { List<Object> a = new Object[n].ToList(); List<Object> b = new List<object>(); while (a.Count > 2) { a.RemoveRange(0, 3); b.Add(new Object()); } return b.Count; } |
溶液(FMA)图书馆的使用功能,工程的任何积极的编号:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <stdio.h> #include <math.h> int main() { int number = 8;//Any +ve no. int temp = 3, result = 0; while(temp <= number){ temp = fma(temp, 1, 3); //fma(a, b, c) is a library function and returns (a*b) + c. result = fma(result, 1, 1); } printf(" %d divided by 3 = %d ", number, result); } |
看我的另一个答案。
使用cblas部分包括AS,OS X的accelerate框架。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [02:31:59] [william@relativity ~]$ cat div3.c #import <stdio.h> #import <Accelerate/Accelerate.h> int main() { float multiplicand = 123456.0; float multiplier = 0.333333; printf("%f * %f ==", multiplicand, multiplier); cblas_sscal(1, multiplier, &multiplicand, 1); printf("%f ", multiplicand); } [02:32:07] [william@relativity ~]$ clang div3.c -framework Accelerate -o div3 && ./div3 123456.000000 * 0.333333 == 41151.957031 |
第一:
1 | x/3 = (x/4) / (1-1/4) |
然后找出如何求解x/(1-y):
1 2 3 4 5 6 | x/(1-1/y) = x * (1+y) / (1-y^2) = x * (1+y) * (1+y^2) / (1-y^4) = ... = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i)) / (1-y^(2^(i+i)) = x * (1+y) * (1+y^2) * (1+y^4) * ... * (1+y^(2^i)) |
y=1/4:
1 2 3 4 5 6 7 8 9 | int div3(int x) { x <<= 6; // need more precise x += x>>2; // x = x * (1+(1/2)^2) x += x>>4; // x = x * (1+(1/2)^4) x += x>>8; // x = x * (1+(1/2)^8) x += x>>16; // x = x * (1+(1/2)^16) return (x+1)>>8; // as (1-(1/2)^32) very near 1, // we plus 1 instead of div (1-(1/2)^32) } |
虽然它使用了
很有趣,没有人用一般的划分来回答:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | /* For the given integer find the position of MSB */ int find_msb_loc(unsigned int n) { if (n == 0) return 0; int loc = sizeof(n) * 8 - 1; while (!(n & (1 << loc))) loc--; return loc; } /* Assume both a and b to be positive, return a/b */ int divide_bitwise(const unsigned int a, const unsigned int b) { int int_size = sizeof(unsigned int) * 8; int b_msb_loc = find_msb_loc(b); int d = 0; // dividend int r = 0; // reminder int t_a = a; int t_a_msb_loc = find_msb_loc(t_a); int t_b = b << (t_a_msb_loc - b_msb_loc); int i; for(i = t_a_msb_loc; i >= b_msb_loc; i--) { if (t_a > t_b) { d = (d << 1) | 0x1; t_a -= t_b; // Not a bitwise operatiion t_b = t_b >> 1; } else if (t_a == t_b) { d = (d << 1) | 0x1; t_a = 0; } else { // t_a < t_b d = d << 1; t_b = t_b >> 1; } } r = t_a; printf("==> %d %d ", d, r); return d; } |
其中一个答案中已经给出了按位加法,因此跳过它。
所有答案可能都不是面试官喜欢听到的:
我的回答是:
"I would never do that, who will me pay for such silly things. Nobody
will have an advantage on that, its not faster, its only silly.
Prozessor designers have to know that, but this must then work for all numbers, not only for division by 3"
好吧,我想我们都同意这不是现实世界的问题。为了好玩,下面介绍如何使用ADA和多线程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | with Ada.Text_IO; procedure Divide_By_3 is protected type Divisor_Type is entry Poke; entry Finish; private entry Release; entry Stop_Emptying; Emptying : Boolean := False; end Divisor_Type; protected type Collector_Type is entry Poke; entry Finish; private Emptying : Boolean := False; end Collector_Type; task type Input is end Input; task type Output is end Output; protected body Divisor_Type is entry Poke when not Emptying and Stop_Emptying'Count = 0 is begin requeue Release; end Poke; entry Release when Release'Count >= 3 or Emptying is New_Output : access Output; begin if not Emptying then New_Output := new Output; Emptying := True; requeue Stop_Emptying; end if; end Release; entry Stop_Emptying when Release'Count = 0 is begin Emptying := False; end Stop_Emptying; entry Finish when Poke'Count = 0 and Release'Count < 3 is begin Emptying := True; requeue Stop_Emptying; end Finish; end Divisor_Type; protected body Collector_Type is entry Poke when Emptying is begin null; end Poke; entry Finish when True is begin Ada.Text_IO.Put_Line (Poke'Count'Img); Emptying := True; end Finish; end Collector_Type; Collector : Collector_Type; Divisor : Divisor_Type; task body Input is begin Divisor.Poke; end Input; task body Output is begin Collector.Poke; end Output; Cur_Input : access Input; -- Input value: Number : Integer := 18; begin for I in 1 .. Number loop Cur_Input := new Input; end loop; Divisor.Finish; Collector.Finish; end Divide_By_3; |
其中inputValue是要除以3的数字
1 2 3 4 | SELECT AVG(NUM) FROM (SELECT InputValue NUM from sys.dual UNION ALL SELECT 0 from sys.dual UNION ALL SELECT 0 from sys.dual) divby3 |
如果你提醒自己标准的学校除法,并用二进制进行除法,你会发现在3的情况下,你只需要除法和减法一组有限的值(在这种情况下从0到5)。这些可以用switch语句处理,以去掉算术运算符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | static unsigned lamediv3(unsigned n) { unsigned result = 0, remainder = 0, mask = 0x80000000; // Go through all bits of n from MSB to LSB. for (int i = 0; i < 32; i++, mask >>= 1) { result <<= 1; // Shift in the next bit of n into remainder. remainder = remainder << 1 | !!(n & mask); // Divide remainder by 3, update result and remainer. // If remainder is less than 3, it remains intact. switch (remainder) { case 3: result |= 1; remainder = 0; break; case 4: result |= 1; remainder = 1; break; case 5: result |= 1; remainder = 2; break; } } return result; } #include <cstdio> int main() { // Verify for all possible values of a 32-bit unsigned integer. unsigned i = 0; do { unsigned d = lamediv3(i); if (i / 3 != d) { printf("failed for %u: %u != %u ", i, d, i / 3); return 1; } } while (++i != 0); } |
一般来说,解决这一问题的办法是:
为什么我们不应用大学里学过的定义呢?结果可能效率低下,但很清楚,因为乘法只是一个递归减法,减法是一个加法,那么加法可以通过递归XOR/和逻辑端口组合执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | #include <stdio.h> int add(int a, int b){ int rc; int carry; rc = a ^ b; carry = (a & b) << 1; if (rc & carry) return add(rc, carry); else return rc ^ carry; } int sub(int a, int b){ return add(a, add(~b, 1)); } int div( int D, int Q ) { /* lets do only positive and then * add the sign at the end * inversion needs to be performed only for +Q/-D or -Q/+D */ int result=0; int sign=0; if( D < 0 ) { D=sub(0,D); if( Q<0 ) Q=sub(0,Q); else sign=1; } else { if( Q<0 ) { Q=sub(0,Q); sign=1; } } while(D>=Q) { D = sub( D, Q ); result++; } /* * Apply sign */ if( sign ) result = sub(0,result); return result; } int main( int argc, char ** argv ) { printf("2 plus 3=%d ", add(2,3) ); printf("22 div 3=%d ", div(22,3) ); printf("-22 div 3=%d ", div(-22,3) ); printf("-22 div -3=%d ", div(-22,-3) ); printf("22 div 03=%d ", div(22,-3) ); return 0; } |
就像有人说的…首先让这个工作。注意,算法应该适用于负Q…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <stdio.h> typedef struct { char a,b,c; } Triple; unsigned long div3(Triple *v, char *r) { if ((long)v <= 2) return (unsigned long)r; return div3(&v[-1], &r[1]); } int main() { unsigned long v = 21; int r = div3((Triple*)v, 0); printf("%ld / 3 = %d ", v, r); return 0; } |
这将起作用…
1 | smegma$ curl http://www.wolframalpha.com/input/?i=14+divided+by+3 2>/dev/null | gawk 'match($0, /link to /input/\?i=([0-9.+-]+)/, ary) { print substr( $0, ary[1,"start"], ary[1,"length"] )}' 4.6666666666666666666666666666666666666666666666666666 |
用你的数字代替14和3。
我将使用这个代码来划分所有正数和非浮点数。基本上,您需要将除数位左对齐以匹配被除数位。对于被除数的每个部分(除数的大小),您要检查以确保被除数的部分是否大于除数,然后您要左移然后在第一个注册器中移动。这个概念最初创建于2004年(我相信斯坦福德),这里是一个使用这个概念的C版本。注:(我修改了一下)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | int divide(int a, int b) { int c = 0, r = 32, i = 32, p = a + 1; unsigned long int d = 0x80000000; while ((b & d) == 0) { d >>= 1; r--; } while (p > a) { c <<= 1; p = (b >> i--) & ((1 << r) - 1); if (p >= a) c |= 1; } return c; //p is remainder (for modulus) } |
示例用法:
1 | int n = divide( 3, 6); //outputs 2 |
似乎没有人提到用二进制表示的3的除法标准——偶数和等于奇数的和(类似于十进制的11)。如果一个数可以被3整除,那么有一些使用这种技巧的解决方案需要检查。
我想这可能是迈克尔·伯尔编辑提到的复制品。
3在11座2的冰。
所以只要做长除法(像在中学2)在11座城市。它是更容易吗?即使在基地10比2座。
对每个位的起始位置和最重要的:
决定如果低于11字头的冰。
如果它是输出0。
如果它是不输出1,然后代用品字头的钻头的适当的变更。有只有三例:
1 2 3 | 11xxx -> xxx (ie 3 - 3 = 0) 100xxx -> 1xxx (ie 4 - 3 = 1) 101xxx -> 10xxx (ie 5 - 3 = 2) |
所有其他prefixes是unreachable。
重复,直到最低位的位置,你会做的。
1 2 3 4 5 | #!/bin/ruby def div_by_3(i) i.div 3 # always return int http://www.ruby-doc.org/core-1.9.3/Numeric.html#method-i-div end |
如果我们考虑
1 2 3 4 | def divBy3(n): return n.__div__(3) print divBy3(9), 'or', 9//3 |
采用Linux shell脚本:
1 2 3 4 5 6 7 8 9 |
看我的另一个答案。
你可以考虑使用一个类似于图/树的结构来解决这个问题。基本上,生成的顶点数量等于要除以3的数字。然后将每个未配对的顶点与其他两个顶点配对。
粗伪代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function divide(int num) while(num!=0) Add a new vertice to vertiexList. num-- quotient = 0 for each in vertexList(lets call this vertex A) if vertexList not empty Add an edge between A and another vertex(say B) else your Remainder is 1 and Quotient is quotient if vertexList not empty Add an edge between A and another vertex(say C) else your remainder is 2 and Quotient is quotient quotient++ remove A, B, C from vertexList Remainder is 0 and Quotient is quotient |
这显然是可以优化的,复杂程度取决于你的数字有多大,但是如果你能做到+和-,它就可以工作了。它只不过是清凉点而已。
它是在与basically,Python字符串比较,和一个状态机。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | def divide_by_3(input): to_do = {} enque_index = 0 zero_to_9 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) leave_over = 0 for left_over in (0, 1, 2): for digit in zero_to_9: # left_over, digit => enque, leave_over to_do[(left_over, digit)] = (zero_to_9[enque_index], leave_over) if leave_over == 0: leave_over = 1 elif leave_over == 1: leave_over = 2 elif leave_over == 2 and enque_index != 9: leave_over = 0 enque_index = (1, 2, 3, 4, 5, 6, 7, 8, 9)[enque_index] answer_q = [] left_over = 0 digits = list(str(input)) if digits[0] =="-": answer_q.append("-") digits = digits[1:] for digit in digits: enque, left_over = to_do[(left_over, int(digit))] if enque or len(answer_q): answer_q.append(enque) answer = 0 if len(answer_q): answer = int("".join([str(a) for a in answer_q])) return answer |
1 2 3 |
这是我小时候祖父教我的方法。它需要+和/运算符,但它使计算变得容易。
把各个数字加在一起,看是不是3的倍数。
但这种方法适用于12以上的数字。
例子:36,
3+6=9,是3的倍数。
42,
4+2=6,是3的倍数。