[探究] 数组循环移动的一种方式
(笔者为普通高三学生,无竞赛经验,如果你有更好的方法,请忽略本文)
最近刷信息技术做到一道题,设今天是星期
答案是
我称之为“启发推导法”。大概记得这种方法老师之前上课讲过,不过他研究得肯定没我透彻。“启发”的意思是,从一个猜测的答案开始,根据逻辑推理,逐渐达到正确的解。
- PART1-求“明天是星期几”
按照习惯性思维,我们应该很快能写出
它的确是符合所有的情况的。
- PART2-求“昨天是星期几”
对于这类情况的处理稍显复杂,同样我们先写出
我们知道对一个数取模时,加上它本身对取模结果没有影响,不妨先
上面只是一个引子,现在我们回归正题——实现数组的循环移动。
无疑,这个操作需要额外的存储空间,因为一个元素的移动必然引起一系列元素的连锁移动,不能直接覆盖否则数据会丢失。考虑一个数组
#include <vector> #include <iostream> void printArray(const std::vector<int> &v) { for (const auto& object : v) std::cout << object << " "; std::cout << std::endl; } int main() { std::vector<int> a{ 1,2,3,4,5,6,7,8 }; int n = a.size(); // a数组的元素个数 int m = 1; // 循环向右移动m个元素 std::vector<int> b(n, 0); std::cout << "Array A: "; printArray(a); std::cout << std::endl; for (; m < n; m++) { for (int i = 0; i < a.size(); i++) b[(i + m - 1) % n + 1] = a[i]; std::cout << "Array B: "; printArray(b); } return 0; }
运行代码,却发现结果和预期不符,为什么呢?因为我们前面的公式是针对
但是,不说以不变应万变,但只要稍作改动——
for (; m < n; m++) { for (int i = 0; i < a.size(); i++) b[(i + m) % n] = a[i]; std::cout << "Array B: "; printArray(b); }
同样地,左移的代码也就顺理成章:
for (; m < n; m++) { for (int i = 0; i < a.size(); i++) b[(i - m % n + n) % n] = a[i]; // m % n 防止索引为负数 std::cout << "Array B: "; printArray(b); }
现在我们来考虑一个变形,之前一直都是对
--END-- 距离第一次选考还有
UPD(2023-04-28):更新了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)