当前位置: 代码迷 >> C# >> 小弟我觉得这个有关问题很难!有人愿意挑战下吗?50分相送
  详细解决方案

小弟我觉得这个有关问题很难!有人愿意挑战下吗?50分相送

热度:149   发布时间:2016-05-05 05:26:34.0
我觉得这个问题很难!有人愿意挑战下吗?50分相送
本帖最后由 bios8086 于 2014-12-22 02:56:30 编辑
创建了一个图的一个边类

struct Edge : IEqualityComparer<Edge>
    {
        private Vertex v_startPoint;

        private Vertex v_endPoint;}


现在希望
    Vertex anve = new Vertex(81.884214, 49.504255);
            Vertex ve = new Vertex(85.693406, 49.773224);
  现在我要  new Edge(anve,ve)  和  new Edge(ve,anve)   

表示的是同一个东西, 有什么办法吗?
表面的意思就是你创建两个点之间的边 不论顶点的先后顺序 都是指的同一个边
------解决思路----------------------
图的一般实现有QuickGraph可以直接用。

如果确实想自己写,这个需求就是实现标准的Equals模式,包括override Equals、GetHashCode方法,实现==、!=两个运算符,实现IEquatable<T>也就是强类型的Equals方法,一共5个方法。其中Equals、==、!=三个方法是标准写法,自己实际需要实现的就是泛型Equals和GetHashCode两个方法。

想要Edge支持相等性判断,Vertex也必须支持,代码如下(ReSharper可以辅助实现Equals模式,自己稍微改改):

public struct Vertex : IEquatable<Vertex>
{
    public readonly float x;
    public readonly float y;

    public Vertex(float x, float y)
    {
        this.x = x;
        this.y = y;
    }

    public bool Equals(Vertex other)
    {
        return x.Equals(other.x) && y.Equals(other.y);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (x.GetHashCode()*397) ^ y.GetHashCode();
        }
    }

    public static bool operator ==(Vertex left, Vertex right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(Vertex left, Vertex right)
    {
        return !left.Equals(right);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        return obj is Vertex && Equals((Vertex)obj);
    }
}

public struct Edge : IEquatable<Edge>
{
    public readonly Vertex start;
    public readonly Vertex end;

    public Edge(Vertex start, Vertex end)
    {
        this.start = start;
        this.end = end;
    }

    public bool Equals(Edge other)
    {
        // 同向反向都认为相等
        return (start.Equals(other.start) && end.Equals(other.end))
            
------解决思路----------------------
 (start.Equals(other.end) && end.Equals(other.start));
    }

    public override int GetHashCode()
    {
        unchecked
        {
            // 同向反向的hash结果相同
            return start.GetHashCode() ^ end.GetHashCode();
        }
    }

    public static bool operator ==(Edge left, Edge right)
    {
        return left.Equals(right);
    }

    public static bool operator !=(Edge left, Edge right)
    {
        return !left.Equals(right);
    }
    
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        return obj is Edge && Equals((Edge)obj);
    }
}

------解决思路----------------------
楼上是个标准做法,再给个另类做法,思路很简单,对Edge的构造函数动一点手脚,让顶点始终按照一种方式保存,这样别的代码都不用动了。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    struct Vertex
    {
        public double X { get; private set; }
        public double Y { get; private set; }
        public Vertex(double x, double y) : this()
        {
            X = x;
            Y = y;
        }
    }
    struct Edge : IEqualityComparer<Edge>
    {
        public Vertex StartPoint { get; private set; } //在这里,我们让顶点只读,否则在顶点赋值的时候,需要重新判断

        public Vertex EndPoint { get; private set; }

        public Edge(Vertex start, Vertex end) : this()
        { 
            // 始终让start存放x大的,如果x一样大,存放y大的。
            if (start.X > end.X 
------解决思路----------------------
 (start.X == end.X && start.Y > end.Y))
            {
                StartPoint = start; EndPoint = end;
            }
            else
            {
                StartPoint = end; EndPoint = start;
            }
        }

        public bool Equals(Edge x, Edge y)
        {
            return x.StartPoint.Equals(y.StartPoint) && x.EndPoint.Equals(y.EndPoint);
        }

        public int GetHashCode(Edge obj)
        {
            return obj.StartPoint.GetHashCode() + obj.EndPoint.GetHashCode();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Edge ed1 = new Edge(new Vertex(1.234, 4.321), new Vertex(5.678, 8.765));
            Edge ed2 = new Edge(new Vertex(1.234, 4.321), new Vertex(5.678, 8.765));
            Console.WriteLine(ed1.Equals(ed1, ed2));
            ed2 = new Edge(new Vertex(5.678, 8.765), new Vertex(1.234, 4.321));
            Console.WriteLine(ed1.Equals(ed1, ed2));
        }
    }
}
  相关解决方案