给定一堆整数,我想将它们转换为基数n,对于每个位,将这些位加起来并用n修改它们。
示例:设n = 3,并假设我想在4,4,4,2中添加mod 3位。基数3中的这些数字是11,11,11,02。最低有效位加起来1 + 1 + 1 + 2 = 5 = 2 mod 3.第二个最低有效位加起来为1 + 1 + 1 + 0 = 3 = 0 mod 3.答案是02 base 3 = 2.或者,如果我们在添加之前没有转换为base 3,并且只是以二进制形式执行,我们有100,100,100,010。从最低有效到最高有效的结果位是:0 + 0 + 0 + 0 = 0 mod 3 ,0 + 0 + 0 + 1 = 1 mod 3,1 + 1 + 1 + 0 = 0 mod 3,所以答案是010 = 2.
n = 2的情况非常简单,你可以对所有东西进行异或。有没有办法概括这个?
答案 0 :(得分:1)
这是红宝石中的小曲:
#! /usr/bin/env ruby
def naryxor(n, terms)
puts "Calculating the #{n}-ary XOR of #{terms.join(", ")}..."
raise "Negative terms are forbidden" if terms.any? { |i| i < 0 }
xor = [] # "Digits" of our n-ary xor result
done = false
while not done
done = true # Assume we're done until proven otherwise
xor.insert(0, 0) # Insert a new total digit at the front
terms = terms.select { |i| i > 0 }.collect do |i|
done = false # Not all remaining terms were zero
digit = i % n # Find the least n-ary digit
rest = (i - digit) / n # shift it off
xor[0] += digit # add it to our xor
rest # Replace this integer with its remainder
end
xor[0] %= n # Take the mod once, after summing.
end
xor[1..-1] # Drop untouched leading digit
end
raise "Usage: ./naryxor.rb arity term term..." if ARGV.size <= 1
puts naryxor(ARGV[0].to_i, ARGV[1..-1].collect(&:to_i)).join("")
运行它:
$ ./naryxor.rb 3 4 4 4 2
Calculating the 3-ary XOR of 4, 4, 4, 2...
02
这只是扩展了传递的整数的n-ary
表示,并做了愚蠢的事情。如果n
被认为是2的幂,我们可以做一些更有趣的位 - 以避免整数除法,但你没有给出这样的保证。
答案 1 :(得分:0)
我不认为有一个数学属性可以导致有效的一般捷径。 XOR适用于基数2的原因是因为XOR具有携带丢弃的附加功能。
简单的递归函数可以应用算法,例如利用Scala的BigInt类进行基本转换:
def sums(radix: Int, digits: List[List[String]]): String =
if(digits exists { _.nonEmpty }) // there's at least 1 bit left to add
(digits.flatMap { _.headOption } // take the 1st bit of all numbers
.map { BigInt(_, radix) } // convert to int representation
.sum
.toInt % radix // modulo by base
).toString +
sums(radix, digits map { _.drop(1) }) // do next most significant bit
else
"" // base case: no digits left to add
def sum(radix: Int, ns: List[Int]): Int =
BigInt(
sums(
radix,
ns // use BigInt to convert from int representation to string
.map { BigInt(_) }
.map { _.toString(radix).split("").drop(1).toList.reverse }
)
.reverse,
radix
).toInt
scala> sum(3, List(4,4,4,2))
res0: Int = 2
您的问题被标记为“性能”,但没有对内存或运行时进行任何其他限制,以便为改进的方法提供信息。