我正面对河内塔问题,我从wikipedia读到了解决它的概念和递归方式,但是我无法看到维基百科中提到的步骤实现中缺少的内容
我在这里看过很多例子,但我不希望我的程序打印步骤,我希望程序解决了在3个集合之间移动“光盘”的问题,在我的代码中我使用3个堆栈来模拟栓。
这是我目前的代码:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
var hs = new HanoiSolver(discs: 3);
hs.Solve();
Console.ReadKey();
}
}
class HanoiSolver
{
private int TotalDiscs { get; set; } = 0;
private Stack<int> FirstPeg { get; set; } = new Stack<int>();
private Stack<int> SecondPeg { get; set; } = new Stack<int>();
private Stack<int> ThirdPeg { get; set; } = new Stack<int>();
public HanoiSolver(int discs = 3)
{
TotalDiscs = discs;
//Create list of items (discs)
var discList = Enumerable.Range(1, TotalDiscs).Reverse();
//Add items (discs) to first peg
foreach (var d in discList)
{
FirstPeg.Push(d);
}
}
public void Solve()
{
if (ThirdPeg.Count != TotalDiscs)
{
PrintPegs();
//Move first item from firstpeg to secondpeg
if (FirstPeg.Any())
{
var fp_f = FirstPeg.Pop();
SecondPeg.Push(fp_f);
}
PrintPegs();
//Move second item from firstpeg to thirdpeg
if (FirstPeg.Any())
{
var fp_s = FirstPeg.Pop();
ThirdPeg.Push(fp_s);
}
PrintPegs();
//Move first item from secondpeg to thirdpeg
if (SecondPeg.Any())
{
var sp_f = SecondPeg.Pop();
ThirdPeg.Push(sp_f);
}
PrintPegs();
Solve();
}
}
private void PrintPegs()
{
var fp = FirstPeg.Select(x => x.ToString()).ToList();
if (fp.Count < TotalDiscs)
{
fp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - fp.Count)));
}
var sp = SecondPeg.Select(x => x.ToString()).ToList();
if (sp.Count < TotalDiscs)
{
sp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - sp.Count)));
}
var tp = ThirdPeg.Select(x => x.ToString()).ToList();
if (tp.Count < TotalDiscs)
{
tp.AddRange(Enumerable.Repeat(string.Empty, (TotalDiscs - tp.Count)));
}
Console.WriteLine($"{"[First Peg]",10}" + $"{"[Second Peg]",10}" + $"{"[Third Peg]",10}");
for (var i = 0; i < TotalDiscs; i++)
{
Console.WriteLine($"{fp[i],10}" +
$"{sp[i],10}" +
$"{tp[i],10}");
}
}
}
答案 0 :(得分:2)
为了制作递归方法,您需要一个或多个基本情况,其中递归将结束,然后一个或多个递归调用将问题分解为更接近其中一个基本情况。对于河内之塔,我们的想法是将n个圆盘从Peg A移动到Peg C只是将n-1从Peg A移动到Peg B,然后将n从A移动到C并最终将n-1个圆盘从C移动到B这最终会让你只能移动一张光盘,这是你的基本情况。这可以通过非常简单的递归方法完成。
private static void Move(
int discs,
Stack<int> fromPeg,
Stack<int> toPeg,
Stack<int> otherPeg)
{
if (discs == 1)
{
toPeg.Push(fromPeg.Pop());
return;
}
Move(discs - 1, fromPeg, otherPeg, toPeg);
toPeg.Push(fromPeg.Pop());
Move(discs -1, otherPeg, toPeg, fromPeg);
}
答案 1 :(得分:0)
实施TOH时,这意味着您不熟悉DS和数据类型。因此,必须使用DS中不存在的数据类型,例如堆栈和队列。所以下面的方法是使用数组。
使用系统; 使用静态System.Console; 命名空间TOH {
class Program
{
// Problem statement
//Create an array tower(a) containing all element in ascending order
public static int[] towerSource = new int[] { 1, 3, 5,6,7,9,11,12,13,14,15,16,17};
//solution statement
//we have two more towers with same capacity, tower(b) as auxiliary and tower(c) as destination
public static int[] towerAuxiliary;
public static int[] towerDestination;
public static void CreateTowers()
{
towerAuxiliary = new int[towerSource.Length];
towerDestination = new int[towerSource.Length];
}
public static void Print(int[] tower)
{
for (int i = 0; i < tower.Length; i++)
Write(tower[i].ToString());
WriteLine("--------next run-------------");
}
//start operation
public static void TOH(int numberOfDisks, int[] source,int[] auxiliary,int[] destination)
{
//check if there is only one disk in source
if(numberOfDisks == 1)
{
//move to destination and come out
towerDestination[numberOfDisks-1] = towerSource[numberOfDisks-1];
Print(towerDestination);
return;
}
//move n-1 disks from source to auxiliary
TOH(numberOfDisks - 1, towerSource, towerAuxiliary, towerDestination);
towerDestination[numberOfDisks-1] = towerSource[numberOfDisks-1];
//move nth disc from source to dest
//this is being handeled by if condition
//move n-1 disks from auxiliary to dest
TOH(numberOfDisks - 1, towerAuxiliary, towerSource, towerDestination);
return;
}
static void Main(string[] args)
{
CreateTowers();
TOH(towerSource.Length, towerSource, towerAuxiliary, towerDestination);
}
}
}