两个整数的映射函数

时间:2014-02-04 11:49:06

标签: algorithm function

SO,

问题

我有两个整数,第一种情况是正数,第二种情况 - 只是整数。我需要从它们创建一个映射函数F到另一个整数值,它将是:

  • 结果应为整数值。对于第一种情况(x>0y>0),正整数值
  • 对称。这意味着F(x,y)= F(y,x)
  • 唯一。这意味着F(x 0 ,y 0 )= F(x 1 ,y 1 )< = > (x 0 = x 1 ^ y 0 = y 1 )V(y 0 = x 1 ^ x 0 = y 1

我的方法

乍一看,对于正整数,我们可以使用像F(x,y)= x 2 + y 2 这样的表达式,但这会失败 - 例如, 89 2 + 23 2 = 13 2 + 91 2 至于第二(常见)案例 - 更多复杂。

用例

这在处理某些事情时可能很有用,这些事情应该是与订单无关的并且需要是唯一的。例如,如果我们想要找到许多数组的笛卡尔积,并且我们希望结果与命令无关,那么<x,z,y>等于<x,y,z>。可以通过以下方式完成:

function decartProductPair($one, $two, $unique=false)
{
   $result = [];
   for($i=0; $i<count($one); $i++)
   {
      for($j=0; $j<count($two); $j++)
      {
         if($unique)
         {
            if($i!=$j)
            {
               $result[$i*$i+$j*$j]=array_merge((array)$one[$i],(array)$two[$j]);
               //           ^
               //           |
               //           +----//this is the place where F(i,j) is needed
            }
         }
         else
         {
            $result[]=array_merge((array)$one[$i], (array)$two[$j]);
         }
      }
   }
   return array_values($result);
}

另一个用例是在一些SQL表中正确地分组发送方和接收方,这样不同的发送方/接收方在保持对称时会有所不同。类似的东西:

SELECT
  COUNT(1) AS message_count,
  sender,
  receiver
FROM
  test
GROUP BY
-- this is the place where F(sender, receiver) is needed:
  sender*sender + receiver*receiver

(通过发布样本我想表明问题肯定与编程有关)

问题

如上所述,问题是 - 什么可以用作F?我希望尽可能简单F。请记住两种情况:

  • 整数x>0y>0F(x,y) > 0
  • 任何整数x,y,因此任何整数F(x,y)

可能F不仅仅是一个表达式 - 而是一些算法可以为任何x,y找到所需的结果(所以也用进行标记)。但是,表达式更好,因为它更像是能够在SQL或PHP或其他任何东西中使用该表达式。 随意编辑标记,因为我不确定这里有两个标记是否足够

4 个答案:

答案 0 :(得分:4)

最简单的解决方案:f(x,y) = x^5 + y^5
没有正整数,可以用不止一种方式写成两个五次幂的总和 至于现在,这是unsolved math problem

答案 1 :(得分:2)

您需要MAX_INTEGER常量,结果需要保留MAX_INTEGER**2(例如:如果两者都是long,则为int)。在这种情况下,一个这样的功能是:

f(x,y) = min(x,y)*MAX_INTEGER + max(x,y)

但是我提出了一个不同的解决方案:使用由str(min(x,y))的串联产生的字符串的哈希函数(比如说md5),一个分隔符(比如“。”)。 )和str(max(x,y))。那就是:

f(x,y) = md5(str(min(x,y)) + "." + str(max(x,y)))

它不是唯一的,但碰撞是非常罕见的,对大多数用例来说可能没问题。如果仍然担心碰撞,请将实际{x,y}与f(x,y)一起保存,并检查碰撞是否发生。

答案 2 :(得分:1)

对输入数字进行排序并对其位进行交错:

x = 5
y = 3
Step 1. Sorting: 3, 5
Step 2. Mixing bits: 11, 101 -> 1_1_, 1_0_1 -> 11011 = 27
So, F(3, 5) = 27

答案 3 :(得分:1)

紧凑的表示是x *(x + 3)/ 2 + y *(x + 1)+(y *(y-1))/ 2,它来自这样的安排:

    x->
y   0    1    3    6   10   15 
|   2    4    7   11   16
v   5    8   12   17
    9   13   18
   14   19   
   20