java中数组循环左移n个位置

2023-11-22

我正在尝试仅使用单个一维数组将数组循环左移 n 个位置。我可以在两个数组中完成它,但我还没有弄清楚如何使用一个数组来完成它。请提出您的建议


实际上有一个聪明的算法可以做到这一点。我们将使用A来表示数组,N表示数组大小,以及n表示要移动的位置数。轮班后您希望i-th元素移动到((i + n) mod N)-th位置,因此我们可以通过以下映射定义新位置:

f(j) := (j + n) mod N  (j = 0,...,N - 1)

该算法背后的总体思想是这样的:我们不想移动元素超过必要的范围,因此理想情况下,我们希望在第一次尝试时将每个元素简单地放置在正确的(移动的)位置。假设我们从位置处的元素开始i。我们想要做的是将元素移动到位置i定位f(i),但是我们会覆盖该位置的元素,所以我们需要首先保存该位置的元素f(i)然后执行转变。一旦我们移动了第一个元素,我们就需要选择另一个元素来移动。由于我们想要节省空间,因此明显的候选者是我们刚刚保存的元素(位于位置的元素f(i))。像以前一样,我们将元素保存在位置f(f(i))然后将我们保存的元素复制到该位置。我们不断重复这个过程(遍历位置i, f(i), f(f(i)), f(f(f(i))), ...)直到我们到达一个我们已经移动的元素(我们保证会这样做,因为位置有限)。如果我们遍历了所有元素,那么我们就完成了,如果没有,那么我们选择另一个元素(尚未移动),比如在位置j,然后重复该过程(经过j, f(j), f(f(j)), f(f(f(j))), ...)。就是这样。但在我们实现这样的算法之前,或者甚至在我们决定这是否确实是一个好的算法之前,我们需要回答几个问题:

  1. 假设我们迭代位置i, f(i), f(f(i)), ...。我们如何知道我们到达的位置已经发生了变化?我们需要保存我们经过的每个位置吗?如果这样做,那么这意味着我们需要保存一个大小为 N 的数组(以覆盖所有位置),并且每次移动元素时我们还需要执行查找。这将使算法效率极低。幸运的是,这不是必需的,因为序列i, f(i), f(f(i)), ...必须在位置处缠绕自身i,所以我们只需要等到到达那个位置即可。我们可以如下证明这个断言:假设我们遇到的第一个重复元素不是i。那么我们必须有两个不同的元素,当移动时会到达相同的位置 - 这是一个矛盾。

  2. 说我们完成了i, f(i), f(f(i)), ...,但仍然有元素保持不变(我们可以通过计算我们移动了多少个元素来判断)。现在我们如何找到职位j含有这样的元素?而且,一旦我们完成了第二次迭代(经历j, f(j), f(f(j)), ...)我们如何找到第三个位置k与一个未移动的元素?等等......这也可能表明我们需要保存一个数组来说明已使用的\未使用的元素,并在每次需要查找未使用的元素时执行查找。然而,我们可以再次放松,因为,正如我们很快将展示的,所有起始位置(我们用i, j and k) 是相邻的。这意味着,如果我们从位置开始i,我们接下来选择i + 1, 进而i + 2, 等等…

  3. 可能是序列i, f(i), f(f(i)), ... and j, f(j), f(f(j)), ... (wherei and j不同)包含共同元素?如果他们这样做,就意味着该算法毫无用处,因为它可能会将同一元素移动两次 - 导致它最终处于错误的位置。那么答案(当然)是它们不能包含共同元素。我们将展示原因。

让我们表示d := gcd(N, n)。对于每一个整数:i = 0,...,d - 1我们定义以下集合:

S(i) := { kd + i | k = 0,...,N/d - 1}

很容易看出集合S(0),...,S(d - 1)一起覆盖集合{0,...,N - 1}。我们还观察到,当划分集合中的元素时S(i) by d,我们剩下余数i,并从不同的集合中划分一个元素S(j) by d会给我们留下不同的余数(j)。因此,没有两个集合包含公共元素。至此,我们确定了集合S(0),...,S(d - 1)形成一个分区{0,...,N - 1}

现在,对于每一个i = 0,...,d - 1,我们将定义集合T(i) as i, f(i), f(f(i)), ...。根据定义f我们可以写T(i)如下:

T(i) = {(kn + i) mod N | k is an integer}

我们观察到,如果x是一个元素T(i),那么我们可以写一些k:

x = (kn + i) mod N = (k(n/d)d + i) mod N

让我们表示z := k(n/d) mod N/d,然后乘以d, 我们有:

kn mod N = zd

因此:

x = (kn + i) mod N = zd + i

Thus, x也在S(i)。同样,如果我们采取一些y from S(i)我们观察到对于某些k:

y = kd + i

Since gcd(n/d, N/d) = 1存在一个q这样q(n/d) mod N/d = 1(模逆),因此我们可以写(乘以kd):

kd = kqn mod N

因此:

y = kd + i = ((kq)n + i) mod N

Thus, y也在T(i)。我们的结论是T(i) = S(i)。从这个事实我们可以很容易地证明我们之前的断言。首先,由于这些集合形成了一个分区{0,...,N - 1}第三个断言(没有两个序列包含公共元素)得到满足。二、由集合的定义S(i)我们可以带任何一组d中的相邻元素{0,...N - 1}并且它们中的每一个都会被放置在不同的集合中。这满足了第二个断言。

这意味着什么是我们可以旋转所有元素的位置0, d, 2d, ..., (N/d - 1)d通过简单地替换位置处的元素n mod N元素位于位置0, 位置处的元素2n mod N元素位于位置n mod N,依此类推……直到我们返回到位置上的元素0(我们确信这将会发生)。这是一个伪代码示例:

temp <- A[0]
j <- N - (n mod N)
while j != 0 do
    A[(j + n) mod N] <- A[j];
    j <- (j - n) mod N
A[n mod N] <- temp;

这涵盖了整个集合S(0)。覆盖其余的集合,即S(1), … ,S(d-1),我们将简单地迭代每个集合,就像我们对第一个集合所做的那样:

for i <- 0 to d - 1
    temp <- A[i]
    j <- N - ((n - i) mod N)
    while j != i do
        A[(j + n) mod N] <- A[j];
        j <- (j - n) mod N
    A[(i + n) mod N] <- temp;

请注意,虽然我们有两个嵌套循环,但每个元素仅移动一次,并且我们使用O(1)空间。 Java 中的实现示例:

public static int gcd(int a, int b) {
    while(b != 0) {
        int c = a;
        a = b;
        b = c % a;
    }
    return a;
}

public static void shift_array(int[] A, int n) {
    int N = A.length;
    n %= N;
    if(n < 0)
        n = N + n;
    int d = gcd(N, n);
    for(int i = 0; i < d; i++) {
        int temp = A[i];
        for(int j = i - n + N; j != i; j = (j - n + N) % N)
            A[(j + n) % N] = A[j];
        A[i + n] = temp;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中数组循环左移n个位置 的相关文章

  • 如何使用 SimpleDateFormat 解析多种格式的日期

    我正在尝试解析文档中的一些日期 用户似乎以类似但不完全相同的格式输入了这些日期 以下是格式 9 09 9 2009 09 2009 9 1 2009 9 1 2009 尝试解析所有这些内容的最佳方法是什么 这些似乎是最常见的 但我想让我困扰
  • 使用 RecyclerView 适配器在运行时更改布局屏幕

    我有两个布局文件 如下所示 如果列表中存在数据 则我显示此布局 当列表为空时 我会显示此布局 现在我想在运行时更改布局 当用户从列表中删除最后一项时 我想将布局更改为第二张图片中显示的 空购物车布局 In getItemCount Recy
  • Condition 接口中的 signalAll 与对象中的 notificationAll

    1 昨天我才问过这个问题条件与等待通知机制 https stackoverflow com questions 10395571 condition vs wait notify mechanism 2 我想编辑相同的内容并在我的问题中添加
  • 无法在 Spring Boot 测试中模拟 persistenceContext

    我正在使用带有 Mockito 框架的 spring boot 测试来测试我的应用程序 存储库类 EntityManager 之一作为参考 我的班级如下所示 Repository Transactional Slf4j public cla
  • 如何从 Retrofit2 获取字符串响应?

    我正在做 android 正在寻找一种方法来执行超级基本的 http GET POST 请求 我不断收到错误 java lang IllegalArgumentException Unable to create converter for
  • 将表值参数与 SQL Server JDBC 结合使用

    任何人都可以提供一些有关如何将表值参数 TVP 与 SQL Server JDBC 一起使用的指导吗 我使用的是微软提供的6 0版本的SQL Server驱动程序 我已经查看了官方文档 https msdn microsoft com en
  • Node.js - console.log 不显示数组中的项目,而是显示 [Object]

    我在注销对象内数组的内容时遇到问题 实际的物体看起来像这样 var stuff accepted item1 item2 rejected response Foo envelope from The sender to new item1
  • Java 8 中函数式接口的使用

    这是来自的后续问题Java 8 中的 双冒号 运算符 https stackoverflow com questions 20001427 double colon operator in java 8其中 Java 允许您使用以下方式引用
  • Java - 返回值是否会中断循环?

    我正在编写一些基本上遵循以下格式的代码 public static boolean isIncluded E element Node
  • JavaScript 中数组的 HTML 数据列表值

    我有一个简单的程序 它必须从服务器上的文本文件中获取值 然后将数据列表填充为输入文本字段中的选择 为此 我想要采取的第一步是我想知道如何动态地将 JavaScript 数组用作数据列表选项 我的代码是
  • Dispatcher-servlet 无法映射到 websocket 请求

    我正在开发一个以Spring为主要框架的Java web应用程序 特别使用Spring core Spring mvc Spring security Spring data Spring websocket 像这样在 Spring 上下文
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • Linux 上有关 getBounds() 和 setBounds() 的 bug_id=4806603 的解决方法?

    在 Linux 平台上 Frame getBounds 和 Frame setBounds 的工作方式不一致 这在 2003 年就已经有报道了 请参见此处 http bugs java com bugdatabase view bug do
  • 将图像添加到自定义 AlertDialog

    我制作了一个 AlertDialog 让用户可以从我显示的 4 个选项中选择一个 前 3 个让他们在单击号码时直接拨打号码 第 4 个显示不同的视图 现在看起来是这样的 由于第四个选项的目的是不同的任务 我想让它看起来不同 因为用户可能会感
  • Java的-XX:+UseMembar参数是什么

    我在各种地方 论坛等 看到这个参数 并且常见的答案是它有助于高并发服务器 尽管如此 我还是找不到 sun 的官方文档来解释它的作用 另外 它是Java 6中添加的还是Java 5中存在的 顺便说一句 许多热点虚拟机参数的好地方是这一页 ht
  • Android - 9 补丁

    我正在尝试使用 9 块图片创建一个新的微调器背景 我尝试了很多方法来获得完美的图像 但都失败了 s Here is my 9 patch 当我用Draw 9 patch模拟时 内容看起来不错 但是带有箭头的部分没有显示 或者当它显示时 这部
  • Hibernate 和可序列化实体

    有谁知道是否有一个框架能够从实体类中剥离 Hibernate 集合以使它们可序列化 我查看了 BeanLib 但它似乎只进行实体的深层复制 而不允许我为实体类中的集合类型指定实现映射 BeanLib 目前不适用于 Hibernate 3 5
  • Android AutoCompleteTextView 带芯片

    我不确定我是否使用了正确的词语来描述此 UI 功能 但我已附上我希望在我的应用程序中实现的目标的快照 它由 Go SMS 使用 用户在编辑文本中键入联系人 在用户从完成下拉列表中选择联系人后 该联系人将被插入到编辑文本中 如附图所示 编辑文
  • 在 Javascript 中减少/分组数组

    基于this https stackoverflow com a 40774906 3254598例如 我想以稍微不同的方式按对象进行分组 结果应该如下 key audi items make audi model r8 year 2012
  • Android 和 Java 中绘制椭圆的区别

    在Java中由于某种原因Ellipse2D Double使用参数 height width x y 当我创建一个RectF在Android中参数是 left top right bottom 所以我对适应差异有点困惑 如果在 Java 中创

随机推荐

  • 从嵌套堆栈导航器导航到根屏幕

    我是新来反应并试图自己学习它 我在将用户从嵌套堆栈导航器屏幕导航回根屏幕时遇到问题 这是我的一些课程 索引 android js import React Component from react import AppRegistry St
  • Python - 字典中的值求和

    我有一个非常简单的清单 example list points 400 gold 2480 points 100 gold 610 points 100 gold 620 points 100 gold 620 我怎样才能总结所有gold价
  • Castle Windsor:如何从代码中指定构造函数参数?

    假设我有以下课程 MyComponent IMyComponent public MyComponent int start at 我可以通过 xml 向温莎城堡注册它的实例 如下所示
  • Google Play 说明中从一个应用程序到另一应用程序的链接

    我在 Google Play 商店中有两个应用程序 是否可以在第一个描述中创建从一个到另一个的 http 链接 Google Play 说明不支持链接 那不是真的 您可以添加指向 Google Play 中其他应用程序的链接 a tag 例
  • 带有 Java 5 的泽西岛

    可与 Java 5 一起运行的最新版本的 Jersey 是什么 我找到了泽西岛 1 3 文档说需要 Java 6 但我在查找以前版本的文档时遇到了麻烦 如果你被 Java 5 困住了 你需要使用球衣1 2 如果版本对你来说还不够成熟 请尝试
  • usr/bin/ld: 找不到 -l

    我正在尝试编译我的程序 但它返回此错误 usr bin ld cannot find l
  • android蓝牙连接在489次成功连接后失败

    不幸的是 我的安卓蓝牙有一些问题 对于我的测试环境 我使用带有 Android 4 4 2 的 Nexus 4 我的 PC 上有一个 Java 应用程序 它使用 bluecove 作为客户端建立 SPP 连接 该程序正在寻找特殊的服务名称并
  • 在 Mac 上安装 pycurl

    我对 python 非常陌生 需要帮助在我的机器上安装 pycurl 库 我现在正在运行 python 2 7 一个简短的教程将不胜感激 使用两种方法之一 方法一 须藤easy install pycurl 方法二 pip 安装 pycur
  • SSE2 有符号整数溢出未定义吗?

    有符号整数溢出在 C 和 C 中未定义 但是 有符号整数在单个字段内溢出又如何呢 m128i 换句话说 这种行为是在英特尔标准中定义的吗 include
  • Java - 将字符串转换为有效的 URI 对象

    我正在尝试获得一个java net URI对象从一个String 该字符串包含一些字符 需要用其百分比转义序列替换 但是当我使用 URLEncoder 用 UTF 8 编码对字符串进行编码时 甚至 也被替换为转义序列 如何从 String
  • Linq Dynamic ParseLambda 无法解析

    我正在尝试使用我在这里找到的示例代码来完成我正在处理的事情 如何将字符串转换为其等效的 LINQ 表达式树 在解决方案中 作者使用了以下内容 var e DynamicExpression ParseLambda new p null ex
  • MVC自定义roleprovider如何将其挂接到HttpContext.Current.User.IsInRole("myrole")

    我有一个 MVC 应用程序 我为其编写了一个自定义角色提供程序 如下所示 using System using System Collections Generic using System Linq using System Web us
  • 单击“下一步”按钮后,如何将 ListView 中的列表项显示限制为 10 和下 10 个

    我有一个包含 100 个项目的列表视图 我想显示前 10 个项目 单击 下一步 按钮时 我必须显示下一个 10 个项目 即从 11 到 20 我有获取前 10 个项目的代码 public int getCount return 10 但如何
  • 从文本中提取位置的方法?

    从自由文本中提取位置的推荐方法是什么 我能想到的是使用正则表达式规则 例如 单词 在位置 但还有比这更好的方法吗 我还可以考虑建立一个包含国家和城市名称的查找哈希表 然后将文本中提取的每个标记与哈希表的标记进行比较 有人知道更好的方法吗 编
  • 错误:require.paths 被删除。使用node_modules文件夹或NODE_PATH环境变量代替

    我刚刚新安装了 Node js 现在我尝试运行一个简单的脚本 但收到以下错误消息 Error require paths is removed Use node modules folders or the NODE PATH enviro
  • UI- 路由器 -- 在每次路由更改时运行函数 -- 状态名称位于哪里?

    使用 Angularjs 和 UI Router 尝试在每次状态更改时运行一个函数 rootScope on stateChangeStart function toState if toState login UsersService r
  • 如何取消操作表

    我使用此代码在 uiactionsheet 中显示 uipicker 但是当我单击关闭按钮时 我想从视图中删除操作表 那么删除 actionSheet 表单视图的代码应该是什么 BOOL textFieldShouldBeginEditin
  • JavaScript 初学者:在 JavaScript 中使用 JSON 和对象

    我有一些 JSON 返回到浏览器 就像这个 产品 Title School Bag Image images school bag jpg 我希望这些数据成为 产品 对象 这样我就可以使用原型方法 例如toHTMLImage 返回产品的 H
  • 金字塔和 .ini 配置

    每个 Pyramid 应用程序都有一个关联的 ini 文件 其中包含其设置 例如 默认值可能如下所示 app main use egg MyProject pyramid reload templates true pyramid debu
  • java中数组循环左移n个位置

    我正在尝试仅使用单个一维数组将数组循环左移 n 个位置 我可以在两个数组中完成它 但我还没有弄清楚如何使用一个数组来完成它 请提出您的建议 实际上有一个聪明的算法可以做到这一点 我们将使用A来表示数组 N表示数组大小 以及n表示要移动的位置