【问题标题】:How to convert a string or integer to binary in Ruby?如何在 Ruby 中将字符串或整数转换为二进制?
【发布时间】:2022-01-13 11:05:11
【问题描述】:

如何将整数 0..9 和数学运算符 + - * / in 创建为二进制字符串。 例如:

 0 = 0000,
 1 = 0001, 
 ...
 9 = 1001

有没有办法在不使用库的情况下使用 Ruby 1.8.6 做到这一点?

【问题讨论】:

  • 当您说要将数学运算符转换为二进制字符串时,您究竟是什么意思?使用用二进制编写的 ASCII 表示?
  • 我猜你想做流行的遗传算法? :-)

标签: ruby binary encode


【解决方案1】:

您可以使用Integer#to_s(base)String#to_i(base)

Integer#to_s(base) 将十进制数转换为表示指定基数的字符串:

9.to_s(2) #=> "1001"

反之则用String#to_i(base):

"1001".to_i(2) #=> 9

【讨论】:

  • @TomRavenscroft 另外,您可以使用("%08b" % int)("%08b" % string) 返回固定位数。
  • 出色的迈克,出色的鲁比!
  • -9.to_s(2) => "-1001" 有人能解释一下吗?
  • 对于像我一样被@decay的代码迷惑的人,他正在使用'sprintf':apidock.com/ruby/Kernel/sprintf
  • @user1201917 这有什么问题? 9 是二进制的1001
【解决方案2】:

我问了a similar question。根据@sawa 的回答,以二进制格式表示字符串中整数的最简洁方法是使用字符串格式化程序:

"%b" % 245
=> "11110101"

您还可以选择字符串表示的长度,如果您想比较固定宽度的二进制数,这可能很有用:

1.upto(10).each { |n| puts "%04b" % n }
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010

【讨论】:

  • 我做了一些本地测试将整数转换为二进制字符串,但结果显示像245.to_s(2)这样的代码会比"%b" % 245
  • 这也不适用于负值。
【解决方案3】:

借鉴 bta 的查找表理念,您可以使用块创建查找表。值在第一次访问和存储时生成以供以后使用:

>> lookup_table = Hash.new { |h, i| h[i] = i.to_s(2) }
=> {}
>> lookup_table[1]
=> "1"
>> lookup_table[2]
=> "10"
>> lookup_table[20]
=> "10100"
>> lookup_table[200]
=> "11001000"
>> lookup_table
=> {1=>"1", 200=>"11001000", 2=>"10", 20=>"10100"}

【讨论】:

    【解决方案4】:

    您自然会在实际程序中使用Integer#to_s(2)String#to_i(2)"%b",但是,如果您对翻译的工作原理感兴趣,此方法使用基本运算符计算给定整数的二进制表示:

    def int_to_binary(x)
      p = 0
      two_p = 0
      output = ""
    
      while two_p * 2 <= x do
        two_p = 2 ** p
        output << ((two_p & x == two_p) ? "1" : "0")
        p += 1
      end
    
      #Reverse output to match the endianness of %b
      output.reverse
    end
    

    检查它是否有效:

    1.upto(1000) do |n|
      built_in, custom = ("%b" % n), int_to_binary(n)
      if built_in != custom
        puts "I expected #{built_in} but got #{custom}!"
        exit 1
      end
      puts custom
    end
    

    【讨论】:

      【解决方案5】:

      如果您只使用单个数字 0-9,则构建查找表可能会更快,这样您就不必每次都调用转换函数。

      lookup_table = Hash.new
      (0..9).each {|x|
          lookup_table[x] = x.to_s(2)
          lookup_table[x.to_s] = x.to_s(2)
      }
      lookup_table[5]
      => "101"
      lookup_table["8"]
      => "1000"
      

      使用数字的整数或字符串表示对该哈希表进行索引将产生其二进制表示为字符串。

      如果您要求二进制字符串长度为特定位数(保留前导零),请将x.to_s(2) 更改为sprintf "%04b", x(其中4 是要使用的最小位数)。

      【讨论】:

      • @bta- 我正在将所有这些字符编码为二进制,这样我就可以在遗传算法中使用它们。我真的很喜欢编码/解码查找表的想法,因为该集合限制为 0..9 和 +-*/
      【解决方案6】:

      在 ruby​​ Integer 类中,to_s 被定义为接收称为base 的非必需参数基数,如果要接收字符串的二进制表示,则传递 2。

      这里是String#to_s官方文档的链接

        1.upto(10).each { |n|  puts n.to_s(2) }
      

      【讨论】:

      • 如果您可以编辑它并描述代码如何解决问题,这个答案会显着改善
      【解决方案7】:

      如果您正在寻找我使用的 Ruby 类/方法,并且我还包含了测试:

      class Binary
        def self.binary_to_decimal(binary)
          binary_array = binary.to_s.chars.map(&:to_i)
          total = 0
      
          binary_array.each_with_index do |n, i|
            total += 2 ** (binary_array.length-i-1) * n
          end
          total
         end
      end
      
      class BinaryTest < Test::Unit::TestCase
        def test_1
         test1 = Binary.binary_to_decimal(0001)
         assert_equal 1, test1
        end
      
       def test_8
          test8 = Binary.binary_to_decimal(1000)
          assert_equal 8, test8
       end
      
       def test_15
          test15 = Binary.binary_to_decimal(1111)
          assert_equal 15, test15
       end
      
       def test_12341
          test12341 = Binary.binary_to_decimal(11000000110101)
          assert_equal 12341, test12341
       end
      end
      

      【讨论】:

        【解决方案8】:

        我迟到了将近十年,但如果有人仍然来到这里并想在不使用像 to_S 这样的内置函数的情况下找到代码,那么我可能会有所帮助。

        找到二进制文件

        def find_binary(number)
          binary = []  
          until(number == 0)
            binary << number%2
            number = number/2
          end
          puts binary.reverse.join
        end
        

        【讨论】:

          猜你喜欢
          • 2018-12-11
          • 2011-05-18
          • 2017-04-25
          • 2012-02-27
          • 1970-01-01
          • 1970-01-01
          • 2018-03-01
          • 1970-01-01
          相关资源
          最近更新 更多