2014年11月05日

C#で座標データの整列

   このエントリーをはてなブックマークに追加 Clip to Evernote
どう書く?orgに感謝を込めて」シリーズ その46

■問題 (出題者: odz さん)
(x, y) の座標情報を以下の2種類の方法で整列する機能を実現してください。
* (x, y) の辞書順(まず x で昇順に整列して、xが同じデータに対して yで昇順に整列する)
* (0, 0) からの距離の昇順
データの表現方法はタプルなり構造体/オブジェクトなり各自で適当に選んで下さい。

データの表現には、タプルではなく、独自に定義した Pointクラスを使いました。
辞書順、距離順ともに、LINQ to Object を使えば簡単にできますね。

using System;
using System.Collections.Generic;
using System.Linq;

namespace Doukaku.Org {
    class Program {
        static void Main(string[] args) {
            // テストデータの作成
            List<Point> list = new List<Point>();
            Random rnd = new Random();
            for (int i = 0; i < 10; i++) {
                list.Add(new Point { X = rnd.Next(0, 10), Y = rnd.Next(0, 10) });
            }
            // テストデータを表示
            list.ForEach(Console.WriteLine);
            Console.WriteLine();

            Console.WriteLine("辞書順でソート");
            var r1 = SortByLexicalOrder(list);
            r1.ForEach(Console.WriteLine);
            Console.WriteLine();

            Console.WriteLine("距離順でソート");
            var r2 = SortByDistance(list);
            r2.ForEach(Console.WriteLine);

            Console.ReadLine();
        }

        //(x, y) の辞書順でソート
        private static IOrderedEnumerable<Point> SortByLexicalOrder(IEnumerable<Point> list) {
            return list.OrderBy(p => p.X).ThenBy(p => p.Y);
        }

        // (0, 0) からの距離の昇順でソート
        private static IOrderedEnumerable<Point> SortByDistance(IEnumerable<Point> list) {
            return list.OrderBy(p => p.X * p.X + p.Y * p.Y);
        }
    }

    class Point {
        public int X { get; set; }
        public int Y { get; set; }
        public override string ToString() {
            return string.Format("({0},{1})", X, Y);
        }
    }
}


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52383413