首页 > 解决方案 > 在大字符串的情况下,“sum”函数无法按预期工作

问题描述

在 Ruby 中,#sum用于计算

  1. 数组之和
  2. 基于函数或条件的数组的总和
  3. 字符串(不是字符数组)中的代码点总和ASCII( ),即ord'abcd'.sum # => 394

第三个问题如下

对于下面的字符串,

AwotIJHOAIJSRoieJHOjasOIADaoiHAOHJAOIJGOIajdOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMEOIFMASKDJQOWJGOJOASJOIQWOGIMASOIDMOQWIROQIGJOIAMSFOAIJGIHIWUNVNZMXCNXCKJQOWRIEOGSDGSPOKSDLAMKMROQIJRDFLKMZXOIAJSQPIRKLMAdglkaSFAJOIAJFOIQWJEOIQJKAMCLKACMALKSDLAKWEQANLEIRJRQFIJAOIVAWOTIJHOAIJSROIEJHOJASOIADAOIHAOHJAOIJGOIAJDOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMASODLQWKEJOIFJLKMALSKQIOWELKMZLXKMFALSFJQOIWEAOISFWIDHGPSODRJAWOPIJHOIDJOIAJTGIOJAORAJWOIJHOFMAOIFMOIPDMOAIPWJTOPIJDOIFjawoiRJOIpjmaioGJIGHAIJRHQHQIUEIvnaksJDNWIORQIOPEGHIDVNAJKNASIPHRQEUITHIUHDNAJSNWIHJQIWJQEOIGOIDVNAKOSDNAOPWPJQOPIWTJQEOIPGDPJFNASPJNQWOIRQWIOTOIVNAKSFNAIOAWOTIJHOAIJSROIEJHOJASOIADAOIHAOHJAOIJGOIAJDOIQWJTOIGJDOINCOIASORIOGIMAOIMEORIQEMOIGMASODLQWKEJOIFJLKMALSKQIOWELKMZLXKMFALSFJQOIWEAOISFWIDHGPSODRJAWOPIJHOIDJoiajTGIOJAORAJWOIJHOFMAOIFMOIPDMOAIPWJTOPIJDOIFJAWOIRJOIPJMAIOGJIGHAIJRHQHQIUEIVNAKSJDNWIORQIOPEGHIDVIPNWIHJQIWJQEOIGOIDVNAKOSDNAOPWPJQOPIWTJqeoIPGDPJFNASPJNQWJQWOIRJgonasKFAWOEJQWOIJOGALKFNASLFKqeqOFIJAOISFJAOISFJAWOI

很大,(1000字符),以下程序不起作用

putc gets.upcase.sum/~/$/

它适用于所有其他较小大小的字符串。上面的输出必须是K. 但它显示\9

但如果我这样做

putc gets.upcase.chars.sum(&:ord)/~/$/

它显示K. 但是前一个为所有其他字符串提供了正确的输出,除了像这样的大字符串。

这里有什么问题?

编辑:试试在线链接

在线尝试!

标签: ruby

解决方案


Sum of ASCII codepoints (ord) in a string (not char array) i.e. 'abcd'.sum # => 394

I've actually never heard of String#sum before, despite being fairly knowledgeable in the language. So I looked it up:

Returns a basic n-bit checksum of the characters in str, where n is the optional Integer parameter, defaulting to 16. The result is simply the sum of the binary value of each byte in str modulo 2**n - 1. This is not a particularly good checksum.

And sure enough, using your example input string, that's why we get:

str.chars.map(&:ord).sum
  # => 77090
str.sum
  # => 11554

The values are different because 77090 > 2**15. Moreover, 77090 % 2**15 == 11554.

If you use a larger value for n, the (check)sum is what you expected:

str.sum(100)
  #=> 77090

推荐阅读