今天看到了两篇博文《关于一道C#上机题的一点想法》和《关于 》,都是说约瑟夫环的OO实现,这两篇文章给了我很好的启发,但是二者的实现和我相像的还有一些差距,于是忍不住自己动了下手。
今天看到了两篇博文《关于一道C#上机题的一点想法》和《关于<关于一道C#上机题的一点想法> 》,都是说约瑟夫环的OO实现,这两篇文章给了我很好的启发,但是二者的实现和我相像的还有一些差距,于是忍不住自己动了下手。
既然是OO,那肯定要符合OO的原则,最先想到的就是开放封闭原则。对于约瑟夫环哪些是可变的,哪些是不可变的,我思考了一下。
可变的部分:
1、环的长度和起始的位置(这个是最基本的扩展);
2、找到下一个人位置的方式(可以隔三个,也可以隔五个,甚至可以进三个退两个);
3、找到人后所做的操作(简单地输出或是让他跳三跳、给朵大红花);
4、围成圈的不一定是人,阿猫阿狗也可以。
不变的部分:
1、环是肯定不会变的;
2、肯定有一个确定下一个位置的方式;
3、找到人后无论给不给他红花,但他一定要出列,不然游戏玩不完了。
基于以上分析,将不变的部分写了个抽象泛型基类。之所以用抽象,就因为很多变化的东西不能确定;之所以用泛型,就是给阿猫阿狗准备的。

基类
public abstract class JosephusRing<T>
{
private int currentPosition;
protected List<T> ring;
public JosephusRing(int length, int startPosition)
{
CreateRing(length); //将环的构造放到子类来完成,应该算是工厂方法模式吧。
this.currentPosition = startPosition;
}
public void NextStep()
{
currentPosition = Next(currentPosition);
Process(currentPosition);
ring.RemoveAt(currentPosition); //出列是不变的
}
public void RunToEnd()
{
while (ring.Count > 0)
{
NextStep();
}
}
protected abstract int Next(int current); //肯定有方法找到下一个位置,但是怎么找不确定
protected abstract void Process(int current); //找到后要进行一些处理,至于是跳三跳还是戴红花那就不知道了
protected abstract void CreateRing(int length);
}
基类实现了约瑟夫环的最核心操作,接下来的派生就可以按需求来定制。

派生类
public class JosephusRingInt32 : JosephusRing<int>
{
public JosephusRingInt32(int length, int startPosition)
: base(length, startPosition)
{
}
protected override int Next(int current) //从1数到3
{
return (current + 2) % base.ring.Count;
}
protected override void Process(int current) //只是简单地输出
{
Console.WriteLine(base.ring[current].ToString());
}
//构造环的过程只能放到派生类来完成,如果是一圈阿猫,或许你就得给它们依次起个名字
protected override void CreateRing(int length)
{
int[] r = new int[length];
for (int i = 0; i < length; ++i)
r[i] = i + 1;
base.ring = new List<int>(r);
}
}
这个派生类完成了最简单、最传统的操作,当然可以扩展得复杂一些。接下来按要求执行就可以了。

执行
class Program
{
static public void Main()
{
JosephusRingInt32 aRing = new JosephusRingInt32(17, 0);
aRing.RunToEnd();
}
}
结果就不截图了,和《关于<关于一道C#上机题的一点想法> 》一文相同。
以上纯属一己之见,也许对开放封闭原则领会的不是很好,还恳请高手指点。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述