【问题标题】:Using Stopwatch in C#在 C# 中使用秒表
【发布时间】:2019-09-05 07:15:41
【问题描述】:

有谁知道如何在这段代码中添加计时器功能来解决数独难题? 我已经尝试过 Stopwatch 类,但我无法让它工作,因为我不知道该把它放在哪里。我尝试了几个地方,但总是出错。代码的主要目的是有效的,但我想添加一个计时器函数来查看代码运行了多长时间。

using System;

namespace SuDoKu
{
  public class SuDoKu
  {
    private int[,] grid;

    public SuDoKu()
    { 
        grid = new int[9, 9];
    } 
     static void Main(string[] args)
     {
        SuDoKu sdk = new SuDoKu();

        int[,] grd = {
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };

        for(int i = 0; i < 9; i++)
            for(int j = 0; j < 9; j++)
                sdk.EnterToGrid(grd[i, j], new Point(i, j));

        Console.WriteLine("Original Grid"); 

        sdk.Display(); 

        sdk.Solve(sdk.NextAvailableCell(), new Point()); 

        Console.WriteLine("\n\n\nSolved Grid"); 

        sdk.Display(); 

        Console.WriteLine();
    }

    public void Display()
    {
        for(int i = 0; i < 9; i++)
        {
            Console.WriteLine();

            for(int j = 0; j < 9; j++)
            {
                if(ShowFromGrid(new Point(i, j)) == 0) {
                    Console.Write("0 ");
                }
                else
                {
                    Console.Write(ShowFromGrid(new Point(i, j)) + " ");
                }

                if(j == 2 || j == 5)
                {
                    Console.Write("| ");
                }
            }
            if(i == 2 || i == 5) {

                Console.Write("\n------|-------|------ ");
            }
        }
    }
    public void EnterToGrid(int num, Point pos) {
        grid[pos.X, pos.Y] = num;
    }

    public int ShowFromGrid(Point pos) {
        return grid[pos.X, pos.Y];
    }

    public void Solve(Point pos, Point prevPos) {

        if(pos.X < 9 && pos.Y < 9)
        {
            Point posPrev = new Point();

            if(grid[pos.X, pos.Y] == 0)
            {
                for(int i = 1; i <= 9; i++)
                {
                    if(IsThisNumberPossibleInTheGrid(i, pos))
                    {
                        grid[pos.X, pos.Y] = i;

                        posPrev.X = pos.X;

                        posPrev.Y = pos.Y;

                        Point posNext = NextAvailableCell();

                        if(!posNext.Equals(new Point()))

                            Solve(posNext, posPrev);
                    }
                }
                if(grid[pos.X, pos.Y] == 0)
                {
                    if(!prevPos.Equals(new Point()))

                        grid[prevPos.X, prevPos.Y] = 0; 

                    return;
                }
            }
        }
        else
        {
            Point posNext = NextAvailableCell();

            if(!posNext.Equals(new Point()))
                Solve(posNext, pos);
        }
    }

    public Point NextAvailableCell()
    {
        for(int i = 0; i < 9; i++)
            for(int j = 0; j < 9; j++)
                if(grid[i, j] == 0)
                    return new Point(i, j);

        return new Point();
    }

    public bool IsThisNumberPossibleInTheGrid(int num, Point pos) {

        if(IsThisNumberPossibleInTheBlock(num, pos))
        {
            for(int i = 0; i < 9; i++)
            {
                if(grid[i, pos.Y] == num && pos.X != i)
                {
                    return false;
                }

                if(grid[pos.X, i] == num && pos.Y != i)
                {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    public bool IsThisNumberPossibleInTheBlock(int num, Point pos)
    {
        Point Grid = new Point();

        Grid.X = (pos.X >= 0 && pos.X <= 2) ? 0 : ((pos.X >= 3 && pos.X <= 5) ? 3 : ((pos.X >= 6 && pos.X <= 8) ? 6 : -1));
        Grid.Y = (pos.Y >= 0 && pos.Y <= 2) ? 0 : ((pos.Y >= 3 && pos.Y <= 5) ? 3 : ((pos.Y >= 6 && pos.Y <= 8) ? 6 : -1));

        if(!Grid.Equals(new Point()))
        {
            for(int i = Grid.X; i < Grid.X + 3; i++)
            {
                for(int j = Grid.Y; j < Grid.Y + 3; j++)
                {
                    if(grid[i, j] == num && !pos.Equals(new Point(i, j)))
                        return false;
                }
            }
            return true;
        }
        return false;
    }
}

  public class Point
  {
    public int X;

    public int Y;

    public Point()
    {
        this.X = -1;
        this.Y = -1;
    }

    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }

    public bool Equals(Point p)
    {
        return (this.X == p.X && this.Y == p.Y) ? true : false;
    }
  }
}

【问题讨论】:

    标签: c# stopwatch


    【解决方案1】:

    “代码的主要目的是有效的,但我想添加一个计时器函数来查看代码运行了多长时间”

    为此,您可以使用System.Diagnostics.Stopwatch(https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.7.2)。 如果要查看函数执行需要多长时间,请在函数调用之前添加stopWatch.Start(),在函数调用之后添加stopWatch.Stop()。您现在可以根据自己的方便使用stopWatch.Elapsed 查看总时间(以秒/毫秒等为单位)。

    【讨论】:

      【解决方案2】:

      Stopwatch 对象通常用于(就像您在此处所做的那样)测量事情需要多长时间。这里要记住的一件快速的事情是,每件事在启动和停止它之间都需要时间,因此请确保只在它们之间放置你想要的实际代码。

      using System.Diagnostics;
      
      //...
      void StopwatchUsingMethod()
      {
        //A: Setup and stuff you don't want timed
        var timer = new Stopwatch();
        timer.Start();
      
        //B: Run stuff you want timed
        timer.Stop();
      
        TimeSpan timeTaken = timer.Elapsed;
        string foo = "Time taken: " + timeTaken.ToString(@"m\:ss\.fff"); 
      }
      

      Foo 将在此处显示完成所需的分钟、秒和毫秒,但如果花费超过 59 分钟,则会显示为错误。关于 TimeSpan 的更多信息可以在这里找到:https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings

      如果我正确理解您的代码,您希望将所有内容都放在 A 部分中的第一行 sdk.Display(); 之前,并且只在 B 部分中调用 Solve ,所以类似于

      static void Main(string[] args)
      {
        //...
        sdk.Display();
        var timer = new Stopwatch();
      
        timer.Start();
        sdk.Solve(sdk.NextAvailableCell(), new Point());
        timer.Stop();
      
        Console.WriteLine("\n\n\nSolved Grid"); 
        //...you can use the time taken here
      }
      

      【讨论】:

      • 谢谢,这很有帮助。
      猜你喜欢
      • 1970-01-01
      • 2014-06-18
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 2011-05-05
      相关资源
      最近更新 更多