You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用splitAt实现Vec的rotateLeft左循环移位函数?

实现Agda中Vec的rotateLeft函数

嘿,我来帮你补全这个左旋转函数的实现!你想用splitAt的思路完全没问题,这确实是实现循环左移最直观的方式之一。不过要注意一个细节:当输入的偏移量n大于向量长度w时,我们其实只需要移动n mod w次就够了,不然会做很多无效的循环。

下面是完整的实现代码:

open import Data.Nat
open import Data.Nat.DivMod
open import Data.Fin
open import Data.Vec
open import Relation.Nullary.Decidable
open import Relation.Binary.PropositionalEquality

rotateLeft : {A : Set} -> {w : ℕ} -> {w≢0 : False (w ≟ 0)} -> ℕ -> Vec A w -> Vec A w
rotateLeft {w = w} n vec = let
  -- 计算实际需要移动的步数:n对w取模,避免多余的循环
  k = n mod w
  -- 把向量拆成前k个元素和剩下的部分
  (front , back) = splitAt k vec
  -- 把后半部分放在前面,前半部分接在后面,完成左旋转
  in back ++ front

关键细节解释

  • 有效偏移量计算:用n mod w得到k,因为w≢0,这个模运算是合法的,而且k一定小于w——这很重要,因为splitAt只有当k ≤ w时才能正确拆分向量,而k < w刚好满足这个条件,同时避免了拆分出空的后半部分或者前半部分的情况。
  • 拆分与拼接:splitAt k vec会返回一个元组,第一个元素是向量的前k个元素,第二个是剩下的w - k个元素。我们只需要把这两部分反过来拼接,就实现了左移k位的效果:原来的第k+1个元素会变成第一个,原来的第一个元素会跑到第w - k + 1个位置,完美符合循环左移的需求。
  • 非空向量约束:{w≢0 : False (w ≟ 0)}这个约束确保我们不会对空向量执行旋转操作——毕竟空向量旋转多少次都是它自己,而且也会避免模运算中除数为0的问题。

内容的提问来源于stack exchange,提问作者MaiaVictor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:19:13