问候。
我有一个我觉得很贵的java方法,我试图用数学表达式替换一些调用它。问题是,我吮吸数学。我的意思是真的很糟糕。
以下内容应该解释我试图利用的模式。
f(x) -> y
f(x*2) -> f(x)+1
也就是说,每当我将x的值加倍时,y的值将比x / 2的值大1。 以下是一些示例输出:
f(5) -> 6
f(10) -> 7
f(20) -> 8
f(40) -> 9
f(80) -> 10
f(160) -> 11
f(320) -> 12
我目前的做法是蛮力。我循环遍历X并测试在我达到5之前我可以将它减半的次数,最后我添加6.这样做并且比调用原始方法更快。但我一直在寻找更“优雅”或更便宜的解决方案。
接受的回答是那个设法帮助我而不指出我有多愚蠢的人:)
(标题可能很糟糕,因为我不知道我在找什么)
答案 0 :(得分:6)
你是否认为你所看到的基本上是除以5,找到你有两个力量,并为这个力量加6?
“给定Y找出X的强大功能”的一般方法是使用对数。使用计算器尝试将日志64除以日志2,并看到你得到6。
所以 - 除以5,取日志,除以2的对数,然后加6。
答案 1 :(得分:3)
您正在寻找对数(基数2)
如果基数x
为5,基数y
为6,则log2(320/5)+ 6 = 12
在Java中,(Math.log(320 / x) / Math.log(2)) + y
其中x
和y
是原始值(在此示例中为f(5) = 6
)
答案 2 :(得分:1)
你要找的是二进制表示中的位数,(对于基数10和10的对数)由log(x)/ log(2)
给出答案 3 :(得分:1)
这不是答案,但我无法作出评论。考虑一个递归函数:
int someFunc(int n, int times) {
if(n == 0) return 0;
if( n % 2 == 0) return someFunc(n/2, times+1);
else return n+times;
}
它能做你想做的吗?
someFunc(1, 0) -> 1
someFunc(2, 0) -> 2
someFunc(3, 0) -> 3
someFunc(5, 0) -> 5
someFunc(10, 0) -> 6
...
答案 4 :(得分:1)
首先,你的问题没有得到很好的解决。这是一个不应该问一个问题的例子(没有冒犯)。我将认为你的问题是:给定正整数x,找到整数m,n,使得x = m * 2 ^ n,其中m是奇数,然后返回y = f(x)= n + g(m)。因为你没有告诉如何计算奇数x的f(x),我假设给出g(。)。
如果在你的问题中,n不大,使用比简单循环(天真算法)更复杂的算法没有真正的好处。我将提出一个算法,它有利于n很大的情况(比如几百,几千)。我不懂Java,所以我以一般形式呈现算法(使用Python式语法)。
如果你采用x的二进制表示(b_ {N-1} ... b_1 b_0,b_i = 0或1)那么你的问题就会减少到从右边找到第一个比特1(即最低有效比特1) )。假设该位的位置是k(0 <= k <= N-1),则n = k并且m = x>&gt; ķ。我相信找到k的最佳方法是使用二进制搜索,这会产生O(log N)算法。算法如下(&lt;&lt;&gt;&gt;是移位运算符):
Algorithm: Input: x -> Outputs: (m, n)
if x is odd or x == 0: return (x, 0) # x is odd when x & 1 == 1 or x % 2 == 1
N = ceil(log(x, 2)) # ceil: smallest integer larger than the argument
n = 0
orig_x = x
while x & 1 == 0: # if bit 0 is 1 (i.e. x is odd), stop the search
half = int(N/2)
lowerhalf = x & ((1 << half) - 1) # obtain the lower half
if lowerhalf == 0: # all zeros
n += half
x = x >> half
N -= half
else:
x = lowerhalf
N = half
return (orig_x >> n, n)
例如,如果N = 1000(x是1000位整数),则该算法最多需要10次迭代(而在最坏的情况下,朴素算法需要1000次迭代)。但是,实际执行时间取决于如何为1000位长度的整数实现位操作和==运算符。
答案 5 :(得分:0)
确定首先让我们注意到所有输入都是5的倍数,所以我们在输入中取出因子5;我们注意到输出从6开始,所以我们在输出中拉出6。我将这个新函数称为g
:
g(1) 0
g(2) 1
g(4) 2
g(8) 3
g(16) 4
g(32) 5
g(64) 6
现在这个函数希望更加熟悉 - g(x)
对x
的力量来说简单2。为了做到这一点(用Java),我们可以使用java.lang.Math.pow(2, x)
。
剩下的就是从f
获取g
。但这很简单:
f
g
我会留给你的。
答案 6 :(得分:-1)
试试这个:
f(x) = log<sub>2</sub>(x/5) + 6