最有效的方法来计算红宝石的汉明距离?

如何解决最有效的方法来计算红宝石的汉明距离?

| 在ruby中,计算两个无符号整数之间的位差(例如汉明距离)的最有效方法是什么? 例如,我有整数a = 2323409845和b = 178264714​​4。 它们的二进制表示为:
a = 10001010011111000110101110110101
b = 01101010010000010000100101101000
a和b之间的位差为17.。 我可以对它们执行逻辑XOR,但这将给我一个不同的整数!= 17,然后我必须遍历结果的二进制表示并计算1的数目。 计算位差的最有效方法是什么? 现在,计算许多整数序列的位差的答案是否改变?例如。给定2个无符号整数序列:
x = {2323409845,641760420,509499086....}
y = {uint,uint,uint...}
计算两个序列之间的位差的最有效方法是什么? 您是要遍历整个序列,还是有一种更快的方法来一次计算整个序列的差异?     

解决方法

        您可以使用Ruby中优化的String函数来进行位计数,而不是使用纯算术。有了一些快速的基准测试,结果大约快了6倍。
def h2(a,b)
  (a^b).to_s(2).count(\"1\")
end
h1是正常的计算方式,而h2将xor转换为字符串,并计算\“ 1 \”的数量 基准测试:
ruby-1.9.2-p180:001:0>> def h1(a,b)
ruby-1.9.2-p180:002:1*> ret = 0
ruby-1.9.2-p180:003:1*> xor = a ^ b
ruby-1.9.2-p180:004:1*> until xor == 0
ruby-1.9.2-p180:005:2*> ret += 1
ruby-1.9.2-p180:006:2*> xor &= xor - 1
ruby-1.9.2-p180:007:2*> end
ruby-1.9.2-p180:008:1*> ret
ruby-1.9.2-p180:009:1*> end
# => nil
ruby-1.9.2-p180:010:0>> def h2(a,b)
ruby-1.9.2-p180:011:1*> (a^b).to_s(2).count(\"1\")
ruby-1.9.2-p180:012:1*> end
# => nil
ruby-1.9.2-p180:013:0>> h1(2323409845,1782647144)
# => 17
ruby-1.9.2-p180:014:0>> h2(2323409845,1782647144)
# => 17
ruby-1.9.2-p180:015:0>> quickbench(10**5) { h1(2323409845,1782647144) }
Rehearsal ------------------------------------
   2.060000   0.000000   2.060000 (  1.944690)
--------------------------- total: 2.060000sec

       user     system      total        real
   1.990000   0.000000   1.990000 (  1.958056)
# => nil
ruby-1.9.2-p180:016:0>> quickbench(10**5) { h2(2323409845,1782647144) }
Rehearsal ------------------------------------
   0.340000   0.000000   0.340000 (  0.333673)
--------------------------- total: 0.340000sec

       user     system      total        real
   0.320000   0.000000   0.320000 (  0.326854)
# => nil
ruby-1.9.2-p180:017:0>> 
    ,        根据mu的建议,我编写了一个简单的C扩展以使用__builtin_popcount,并使用基准测试证明它比ruby优化的字符串函数至少快3倍。 我看了以下两个教程: 用C扩展Ruby 5分钟内使用C进行Ruby扩展 在我的程序中:
require \'./FastPopcount/fastpopcount.so\'
include FastPopcount

def hamming(a,b)
  popcount(a^b)
end
然后在包含我的程序的目录中,创建一个包含以下文件的文件夹“ PopCount \”。 extconf.rb:
# Loads mkmf which is used to make makefiles for Ruby extensions
require \'mkmf\'

# Give it a name
extension_name = \'fastpopcount\'

# The destination
dir_config(extension_name)

# Do the work
create_makefile(extension_name)
popcount.c:
// Include the Ruby headers and goodies
#include \"ruby.h\"

// Defining a space for information and references about the module to be stored internally
VALUE FastPopcount = Qnil;

// Prototype for the initialization method - Ruby calls this,not you
void Init_fastpopcount();

// Prototype for our method \'popcount\' - methods are prefixed by \'method_\' here
VALUE method_popcount(int argc,VALUE *argv,VALUE self);

// The initialization method for this module
void Init_fastpopcount() {
    FastPopcount = rb_define_module(\"FastPopcount\");
    rb_define_method(FastPopcount,\"popcount\",method_popcount,1); 
}

// Our \'popcount\' method.. it uses the builtin popcount
VALUE method_popcount(int argc,VALUE self) {
    return INT2NUM(__builtin_popcount(NUM2UINT(argv)));
}
然后在popcount目录中运行: 红宝石extconf.rb 使 然后运行程序,就可以了。...最快的方法来在红宝石中进行汉明距离。     ,        Wegner的算法:
def hamm_dist(a,b)
  dist = 0
  val = a ^ b

  while not val.zero?
    dist += 1
    val &= val - 1
  end
  dist
end

p hamm_dist(2323409845,1782647144) # => 17 
    ,        如果打算遵循基于C的路径,则最好将编译器标志
-msse4.2
添加到您的makefile中。这使编译器可以生成基于硬件的“ 9”指令,而无需使用表来生成弹出计数。在我的系统上,速度大约快2.5倍。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-