创建一个方法来查找数字是否是 2 的幂?
Create a method to find if a number is a power of 2?
如果 num
是 2 的幂,我有此代码 return true
。
def is_power_of_two?(num)
result = num.inject(0) {|n1, n2| n2 ** n1}
if result == num
true
else
false
end
end
p is_power_of_two?(16)
不过我一直收到错误消息。我该如何修复和简化此代码?
正如上面评论中指出的那样,您遇到错误是因为您试图对不可迭代对象(int)使用 inject
方法。这是使用建议的 log2
的解决方案
def is_power_of_two?(num)
result = Math.log2(num)
result == Integer(result)
end
注意:对于接近二进制的非常大的数字(例如 2 ^ 64 - 1),将会失败。万无一失的版本(但速度较慢)是:
def is_power_of_two?(num)
while (num % 2 == 0 and num != 0)
num /= 2
end
num == 1
end
如有任何改进,请发表评论。
尝试:
def is_power_of_two?(num)
num != 0 && (num & (num - 1)) == 0
end
解释得很好here(对于 C#,但@GregHewgill 的解释也适用于此)
我会做这样的事情,使用 Ruby 的 Math
模块。
def power_of_two?(n)
Math.log2(n) % 1 == 0
end
或者,如果你想变得很酷:
def power_of_two?(n)
(Math.log2(n) % 1).zero?
end
部分 IRB 输出:
2.1.0 :004 > power_of_two?(2)
=> true
2.1.0 :005 > power_of_two?(32768)
=> true
2.1.0 :006 > power_of_two?(65536)
=> true
此方法假定输入为正整数。
显然,n
是一个非负整数。
代码
def po2?(n)
n.to_s(2).count('1') == 1
end
例子
po2? 0 #=> false
po2? 1 #=> true
po2? 32 #=> true
po2? 33 #=> false
说明
Fixnum#to_s 提供给定基数的整数(接收者)的字符串表示。该方法的参数(默认为 10)是基数。例如:
16.to_s #=> "16"
16.to_s(8) #=> "20"
16.to_s(16) #=> "10"
15.to_s(16) #=> "f"
我们感兴趣的是以 2 为底。对于 2 的幂:
1.to_s(2) #=> "1"
2.to_s(2) #=> "10"
4.to_s(2) #=> "100"
8.to_s(2) #=> "1000"
16.to_s(2) #=> "10000"
对于一些不是2的幂的自然数:
3.to_s(2) #=> "11"
5.to_s(2) #=> "101"
11.to_s(2) #=> "1011"
因此我们希望匹配包含 1
.
的二进制字符串
另一种方式
R = /
\A # match beginning of string ("anchor")
10* # match 1 followed by zero or more zeroes
\z # match end of string ("anchor")
/x # free-spacing regex definition mode
def po2?(n)
(n.to_s(2) =~ R) ? true : false
end
po2?(4) #=> true
po2?(5) #=> false
还有一个用于公路
这使用 Fixnum#bit_length and Fixnum#[]:
def po2?(n)
m = n.bit_length-1
n[m] == 1 and m.times.all? { |i| n[i].zero? }
end
po2? 0 #=> false
po2? 1 #=> true
po2? 32 #=> true
po2? 33 #=> false
这是另一个使用递归的解决方案:
def power_of_2?(number)
return true if number == 1
return false if number == 0 || number % 2 != 0
power_of_2?(number / 2)
end
在我看来,最简单的——但可能有点长——做你需要做的事情的方法就是像这样编写这个递归方法:
def power_of_two?(number)
continue = true
if number == 1
return true
end
if number % 2 != 0
return false
else
while continue == true do
if number.to_f / 2.0 == 2.0
continue = false
return true
else
if number % 2 != 0
continue = false
return false
else
number /= 2
continue = true
end
end
end
end
end
一是二的幂(2^0),所以它首先检查给定的数字是否为1。如果不是,则检查它是否为奇数,因为1是唯一的奇数,是的幂二。
如果它是奇数,则它 return 为 false 并转到 else 语句。它将检查数字除以 2 是否为二,因为那样它显然是 2 的幂。它以浮点数的形式执行此操作,因为 Ruby 中的 5/2 将 return 2.
如果为假,它会再次检查数字是否为奇数——第一轮不需要,之后需要。如果数字不是奇数,它会将数字除以二,然后再循环一次。
这将继续,直到程序通过获得 2 或任何奇数以及 return 分别为 true 或 false 来自行解决。
我 运行 在训练营应用程序准备中进入这个。我不是数学家,不理解其中的一些方法,所以我想为像我这样的人提交一个常识性方法。这需要很少的数学知识,除了知道一个数的二次方将是某个数乘以自身的结果。
def is_power_of_two?(num)
num.times {|n| return true if (n+1) * (n+1) == num}
false
end
此方法计数到从 1 开始的 num 变量,如果(序列中的任何数字乘以自身)等于 num 且如果 num 不为 0(更多信息),则 returns 为真下面)。
示例:
数 = 9
1 * 1 == 9 #=> false
2 * 2 == 9 #=> false
3 * 3 == 9 #=> true
返回 true,方法完成 运行。
#times 方法需要一个大于 0 的整数,因此这种边缘情况是 "handled",因为 #times 不使用“0”作为变量并且 returns false 当在#times 迭代之外。
解决这个问题的另一种方法是与这里的大多数答案相反——我们可以从数字 1 开始,看看这个数字是否是 2 的幂。像这样:
def power_of_two?(num)
product = 1
while product < num
product *= 2
end
product == num
end
我们从1开始,然后将1乘以2,一直乘以2,直到乘积大于num
(product < num
)。一旦我们达到那个条件,我们就停止,退出循环,并检查它是否等于 num
(product == num
)。如果是,则 num
是 2 的幂。
def power_of_two?(num)
num.to_s(2).scan(/1/).length == 1
end
如果 num
是 2 的幂,我有此代码 return true
。
def is_power_of_two?(num)
result = num.inject(0) {|n1, n2| n2 ** n1}
if result == num
true
else
false
end
end
p is_power_of_two?(16)
不过我一直收到错误消息。我该如何修复和简化此代码?
正如上面评论中指出的那样,您遇到错误是因为您试图对不可迭代对象(int)使用 inject
方法。这是使用建议的 log2
def is_power_of_two?(num)
result = Math.log2(num)
result == Integer(result)
end
注意:对于接近二进制的非常大的数字(例如 2 ^ 64 - 1),将会失败。万无一失的版本(但速度较慢)是:
def is_power_of_two?(num)
while (num % 2 == 0 and num != 0)
num /= 2
end
num == 1
end
如有任何改进,请发表评论。
尝试:
def is_power_of_two?(num)
num != 0 && (num & (num - 1)) == 0
end
解释得很好here(对于 C#,但@GregHewgill 的解释也适用于此)
我会做这样的事情,使用 Ruby 的 Math
模块。
def power_of_two?(n)
Math.log2(n) % 1 == 0
end
或者,如果你想变得很酷:
def power_of_two?(n)
(Math.log2(n) % 1).zero?
end
部分 IRB 输出:
2.1.0 :004 > power_of_two?(2)
=> true
2.1.0 :005 > power_of_two?(32768)
=> true
2.1.0 :006 > power_of_two?(65536)
=> true
此方法假定输入为正整数。
显然,n
是一个非负整数。
代码
def po2?(n)
n.to_s(2).count('1') == 1
end
例子
po2? 0 #=> false
po2? 1 #=> true
po2? 32 #=> true
po2? 33 #=> false
说明
Fixnum#to_s 提供给定基数的整数(接收者)的字符串表示。该方法的参数(默认为 10)是基数。例如:
16.to_s #=> "16"
16.to_s(8) #=> "20"
16.to_s(16) #=> "10"
15.to_s(16) #=> "f"
我们感兴趣的是以 2 为底。对于 2 的幂:
1.to_s(2) #=> "1"
2.to_s(2) #=> "10"
4.to_s(2) #=> "100"
8.to_s(2) #=> "1000"
16.to_s(2) #=> "10000"
对于一些不是2的幂的自然数:
3.to_s(2) #=> "11"
5.to_s(2) #=> "101"
11.to_s(2) #=> "1011"
因此我们希望匹配包含 1
.
另一种方式
R = /
\A # match beginning of string ("anchor")
10* # match 1 followed by zero or more zeroes
\z # match end of string ("anchor")
/x # free-spacing regex definition mode
def po2?(n)
(n.to_s(2) =~ R) ? true : false
end
po2?(4) #=> true
po2?(5) #=> false
还有一个用于公路
这使用 Fixnum#bit_length and Fixnum#[]:
def po2?(n)
m = n.bit_length-1
n[m] == 1 and m.times.all? { |i| n[i].zero? }
end
po2? 0 #=> false
po2? 1 #=> true
po2? 32 #=> true
po2? 33 #=> false
这是另一个使用递归的解决方案:
def power_of_2?(number)
return true if number == 1
return false if number == 0 || number % 2 != 0
power_of_2?(number / 2)
end
在我看来,最简单的——但可能有点长——做你需要做的事情的方法就是像这样编写这个递归方法:
def power_of_two?(number)
continue = true
if number == 1
return true
end
if number % 2 != 0
return false
else
while continue == true do
if number.to_f / 2.0 == 2.0
continue = false
return true
else
if number % 2 != 0
continue = false
return false
else
number /= 2
continue = true
end
end
end
end
end
一是二的幂(2^0),所以它首先检查给定的数字是否为1。如果不是,则检查它是否为奇数,因为1是唯一的奇数,是的幂二。
如果它是奇数,则它 return 为 false 并转到 else 语句。它将检查数字除以 2 是否为二,因为那样它显然是 2 的幂。它以浮点数的形式执行此操作,因为 Ruby 中的 5/2 将 return 2.
如果为假,它会再次检查数字是否为奇数——第一轮不需要,之后需要。如果数字不是奇数,它会将数字除以二,然后再循环一次。
这将继续,直到程序通过获得 2 或任何奇数以及 return 分别为 true 或 false 来自行解决。
我 运行 在训练营应用程序准备中进入这个。我不是数学家,不理解其中的一些方法,所以我想为像我这样的人提交一个常识性方法。这需要很少的数学知识,除了知道一个数的二次方将是某个数乘以自身的结果。
def is_power_of_two?(num)
num.times {|n| return true if (n+1) * (n+1) == num}
false
end
此方法计数到从 1 开始的 num 变量,如果(序列中的任何数字乘以自身)等于 num 且如果 num 不为 0(更多信息),则 returns 为真下面)。
示例: 数 = 9
1 * 1 == 9 #=> false
2 * 2 == 9 #=> false
3 * 3 == 9 #=> true
返回 true,方法完成 运行。
#times 方法需要一个大于 0 的整数,因此这种边缘情况是 "handled",因为 #times 不使用“0”作为变量并且 returns false 当在#times 迭代之外。
解决这个问题的另一种方法是与这里的大多数答案相反——我们可以从数字 1 开始,看看这个数字是否是 2 的幂。像这样:
def power_of_two?(num)
product = 1
while product < num
product *= 2
end
product == num
end
我们从1开始,然后将1乘以2,一直乘以2,直到乘积大于num
(product < num
)。一旦我们达到那个条件,我们就停止,退出循环,并检查它是否等于 num
(product == num
)。如果是,则 num
是 2 的幂。
def power_of_two?(num)
num.to_s(2).scan(/1/).length == 1
end