ほぼC#だけのぶろぐ

実行ファイルのパス

.netcore
仕事が.net Frameworkなので、
System.Windows.Forms.Application.StartupPathを使っていたけど
いい加減他を使っておこう。

using System;
using System.Reflection;

namespace SampleCodeCore
{
    class Program
    {
        static void Main(string[] args)
        {
            var assemblyPath = Assembly.GetEntryAssembly().Location;
            Console.WriteLine(assemblyPath);
        }
    }
}


投稿日時: 2020-10-24 22:43:24
更新日時: 2020-10-24 22:43:24

呼び出し元のメソッド名、行数、ファイル名の取得

.netcore
https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.compilerservices.callermembernameattribute?redirectedfrom=MSDN&view=netcore-3.1

using System;

namespace ConsoleAppCS
{
    class Program
    {
        static void Main(string[] args)
        {
            Log("メッセージ1");

            Function1();
        }

        static void Function1()
        {
            Log("メッセージ2");
        }

        static void Log(string message,
        [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
        [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
        [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
        {
            Console.WriteLine("message: " + message);
            Console.WriteLine("member name: " + memberName);
            Console.WriteLine("source file path: " + sourceFilePath);
            Console.WriteLine("source line number: " + sourceLineNumber);
        }
    }
}


message: メッセージ1
member name: Main
source file path: C:\Users\csharp\source\repos\ConsoleApplication1\ConsoleAppCS\Program.cs
source line number: 9
message: メッセージ2
member name: Function1
source file path: C:\Users\csharp\source\repos\ConsoleApplication1\ConsoleAppCS\Program.cs
source line number: 16

投稿日時: 2020-10-24 22:13:24
更新日時: 2020-10-24 22:13:24

クイックソート

アルゴリズム
クイックソート
クイックソート (quicksort) は、1960年にアントニー・ホーアが開発したソートのアルゴリズム。分割統治法の一種。

n個のデータをソートする際の最良計算量および平均計算量はO(nlog n)である。他のソート法と比べて、一般的に最も高速だといわれているが対象のデータの並びやデータの数によっては必ずしも速いわけではなく、最悪の計算量はO(n2)である。また数々の変種がある。 安定ソートではない。


pivot(基準とする値)を選択し、
pivotより左にあるデータでpivotより大きいものはpivotの右側にある要素とシャッフルし
pivotより右にあるデータでpivotより小さいものはpivotの左側にある要素とシャッフルをする。
これによりpivotの位置は確定し、pivotより左と右にある要素について、それぞれ同じ処理を繰り返していく。

※pivotの値が中央の値に近ければ近いほど高率よくソートできるため
 サンプルコードでは、先頭の要素と末尾の要素と中央の要素をとりだし、2番目に大きい値をpivotに採用しています。

例)
6,3,7,5,2,4,1

先頭(6)と末尾(1)と中央(5)を比較し、5をpivotとする。
6,3,7,[5],2,4,1
pivotより左側で5以上値を探す(6)
pivotより右側で5以下値を探す(1)
入れ替える
1,3,7,[5],2,4,6
同様に5以上の値を探す(7)
同様に5以下の値を探す(4)
入れ替える
1,3,4[5],2,7,6
同様に5以上の値を探す(5)
同様に5以下の値を探す(2)
入れ替える
1,3,4,2,[5],7,6
5が確定

|1,3,4,2|[5]|7,6|
pivotの左右に対し同じ処理を繰り返す

1,3,4,2
先頭(1)と末尾(2)と中央(3)を比較し、2をpivotとする。
1,3,4,[2]
pivotより左側で2以上値を探す(3)
pivotより右側で2以下値を探す(2)
入れ替える
1,[2],4,3

|1|[2]|4,3|

1は、これ以上ソートは不要
[1,2]|4,3|

4,3
先頭(4)と末尾(3)と中央(4)を比較し、3をpivotとする。
4,[3]
pivotより左側で2以上値を探す(4)
pivotより右側で2以下値を探す(3)
入れ替える
3,4
[1,2,3,4,5]|7,6|

7,6
先頭(7)と末尾(6)と中央(7)を比較し、6をpivotとする。
7,[6]
pivotより左側で2以上値を探す(7)
pivotより右側で2以下値を探す(6)
入れ替える
[6,7]

1,2,3,4,5,6,7

サンプルコード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Markup;

namespace SampleCode
{
    class Program
    {
        static void Main(string[] args)
        {
            // 20までの数字を生成しシャッフルする
            var data = Program.GenerateData(7);

            // Sort前
            Console.WriteLine(string.Join(',', data));

            // Mergeソート
            Program.QuickSort(data, 0, data.Count -1);

            // Sort後
            Console.WriteLine(string.Join(',', data));
        }

        static void QuickSort(List<int> data, int left, int right)
        {
            var l = left;
            var r = right;

            if(r - l < 1) { return; }

            // 3要素から中央の値をpivotとする
            var pivot = SelectPivot(data, l, r);
            Console.WriteLine("pivot:" + pivot);
            while (true)
            {
                while (data[l] < pivot) { l++; }
                while (pivot < data[r]) { r--; }

                if (r <= l) { break; }

                var temp = data[l];
                data[l] = data[r];
                data[r] = temp;

                l++;
                r--;
            }
            Console.WriteLine(string.Join(',', data));

            QuickSort(data, left, l - 1);
            QuickSort(data, r + 1, right);
        }

        static int SelectPivot(List<int> data, int l, int r)
        {
            int m = (l + r) / 2;

            if(data[m] <= data[l] && data[r] <= data[l])
            {
                return data[m] <= data[r] ? data[r] : data[m];
            }
            else if(data[l] <= data[m] && data[r] <= data[m])
            {
                return data[l] <= data[r] ? data[r] : data[l];
            }
            else
            {
                return data[l] <= data[m] ? data[m] : data[l];
            }
        }

        /// <summary>
        /// 任意の1〜nまでのリストを生成し、Fisher-Yatesシャッフルしたものを返す
        /// </summary>
        /// <param name="maxNumber"></param>
        /// <returns>1〜任意の数字までのシャッフルされたリスト</returns>
        static List<int> GenerateData(int maxNumber)
        {
            // 1未満の場合は空のリストを返す
            if (maxNumber < 1) { new List<int>(); }

            // 1から任意の数字までのリストを生成
            var num = Enumerable.Range(1, maxNumber).ToList<int>();

            // シャッフル
            Random r = new Random();
            for (var i = num.Count() - 1; 0 < i; i--)
            {
                var rand = r.Next(i);

                // 乱数が最大値と同じ時、シャッフル元とシャッフル先が同一となるため何もしない
                if (rand == i) { continue; }

                var temp = num[i];
                num[i] = num[rand];
                num[rand] = temp;
            }

            return num;
        }
    }
}

投稿日時: 2020-08-15 04:22:15
更新日時: 2020-08-15 04:22:15
NextPage