【问题标题】:Mathematically rotate an array of ordered numbers以数学方式旋转有序数字数组
【发布时间】:2016-10-07 12:43:04
【问题描述】:

假设您在给定域中有一组数字,例如:[-4,4]

还假设这组数字在一个数组中,并且按数字顺序,如下所示:

[-4, -3 -2, -1, 0, 1, 2, 3, 4]

现在假设我想为这组数字创建一个新的零点,如下所示:(我选择 -2 作为我的新轴,并且所有元素都相应地移动)

原文:[-4, -3 -2, -1, 0, 1, 2, 3, 4]

归零:[-2, -1 0, 1, 2, 3, 4, -4, -3]

有了新的归零数组,假设我有一个函数叫做:

"int getElementRelativeToZeroPosition(int zeroPos, int valueFromOriginalArray, int startDomain, int endDomain) {...}"

示例用法:

我得到了 3 个原始数组,想看看它映射到归零数组上的位置,零在 -2 上。

getElementRelativeToZeroPosition(-2, 3, -4, 4) = -4

无需为此映射创建任何数组并四处移动元素,我将如何在数学上生成上述函数的所需结果?

【问题讨论】:

    标签: c++ arrays performance mapping


    【解决方案1】:

    我会这样做:

    1. 获取原始零位的索引
    2. 获取新零位置的索引(即在您的示例中为 -2 的索引)
    3. 获取搜索位置的索引(索引为 3)
    4. 计算新零位和原始零位之间的移动向量
    5. 将移动向量应用于搜索位置取模数组大小以执行旋转

    如果您的数组是从零开始的:

    index(0) => 4
    index(-2) => 2
    index(3) => 7
    array_size => 9
    
    move_vector => index(0) - index(-2)
                => 4 - 2 => +2
    
    new_pos(3) => (index(3) + move_vector) modulo array_size
               => (7 + 2) mod 9 => 0
    
    value_at(0) => -4
    

    就是这样

    【讨论】:

      【解决方案2】:

      从数学上讲,如果您有一组由包含范围 [start, stop] 给出的隐式整数,那么选择一个新的零点实际上就是选择一个开始的索引。计算完这个索引后,你可以计算你的查询点的索引(在原始域中),并找到它们之间的差异以获得偏移量:

      例如:

      • 给定:范围 [-4, 4],假设零索引数组 (0,...,8) 对应于范围内的值
        • 长度(范围)=4 - (-4) + 1= 9
      • 选择新的“零点” -2。
        • -2 的索引是-2 - (-4) = -2 + 4 = 2
      • 查询位置 3:
        • 原始范围内的索引:3 - (-4) = 3 + 4 = 7
      • 在归零数组中找到 3 的偏移量:
        • 这是原始数组中索引之间的差异
        • 7 - 2 = 5,所以元素 3 距离元素 -2 有 5 跳。等效地,它是5-len(range) = 5 - 9 = -4 跳跃。您可以拨打min(abs(5), abs(-4)) 看看您喜欢哪一个。

      【讨论】:

        【解决方案3】:

        你可以写一个双链表,头节点指向开头

        struct nodeItem
        {
            nodeItem* pev = nullptr;
            nodeItem* next = nullptr;
            int value = 0;
        }
        
        class Node
        {
        private:
            nodeItem* head;
        
        public:
            void SetHeadToValue(int value);
            ...
        }
        

        最后一个值应该指向第一个值的旁边,所以你有一个循环列表。

        要弄清楚,如果你在列表的末尾,你必须检查项目是否等于头节点

        【讨论】:

        • 我不会说这一定是一个数学解决方案。我正在寻找效率,并且宁愿执行简单的数学运算而不是消耗资源。尽管如此,我还是会考虑将其作为一个选项。
        • 问题是:你是如何使用它的?那你用它干什么?
        • 如果只是从不同的起始位置绘制,那么这种计算速度很快,如果你想添加新的项目,它也很快,如果你是在随机索引上跳跃真的很慢……
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-10
        • 2018-02-13
        • 2010-12-25
        • 2011-09-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多