This commit is contained in:
ninemine
2025-06-29 15:52:06 +08:00
parent 0385ffbd29
commit 981157dfec
8 changed files with 1735 additions and 4 deletions

View File

@@ -0,0 +1,200 @@
using System;
using System.Collections.Generic;
namespace Convention
{
public class PriorityQueue<T> where T : IComparable<T>
{
private int _size;
private int _capacity;
private T[] _elements;
public readonly IComparer<T> _comparer = null;
public readonly Func<T, T, int> _comparer_func = null;
public readonly Comparator _comparator = Comparator.less;
public int Size => _size;
public int Capacity => _capacity;
public int Count => _size;
public bool IsEmpty => _size == 0;
public T Top => _elements[0];
public void Clear()
{
Array.Clear(_elements, 0, _size);
_size = 0;
}
public PriorityQueue(Comparator comparator = Comparator.less, int capacity = 1)
{
_size = 0;
_capacity = Math.Max(1, capacity);
_comparator = comparator;
_elements = new T[_capacity];
}
public PriorityQueue(IComparer<T> comparer, int capacity = 1)
{
_size = 0;
_capacity = Math.Max(1, capacity);
_comparer = comparer;
_elements = new T[_capacity];
}
public PriorityQueue(Func<T, T, int> comparer, int capacity = 1)
{
_size = 0;
_capacity = Math.Max(1, capacity);
_comparer_func = comparer;
_elements = new T[_capacity];
}
private int Compare(T x, T y)
{
if (_comparer != null)
{
return _comparer.Compare(x, y) * (int)_comparator;
}
else if (_comparer_func != null)
{
return _comparer_func(x, y);
}
else
{
return x.CompareTo(y) * (int)_comparator;
}
}
private void ShiftDown()
{
int cur = 0;
int child = 1;
while (child < _size)
{
if (child + 1 < _size && Compare(_elements[child + 1], _elements[child]) < 0)
child++;
if (Compare(_elements[child], _elements[cur]) < 0)
{
Swap(ref _elements[child], ref _elements[cur]);
cur = child;
child = 2 * cur + 1;
}
else break;
}
}
private void ShiftUp()
{
int cur = _size - 1;
int parent = (cur - 1) / 2;
while (cur > 0)
{
if (Compare(_elements[cur], _elements[parent]) < 0)
{
Swap(ref _elements[cur], ref _elements[parent]);
cur = parent;
parent = (cur - 1) / 2;
}
else break;
}
}
private void ExpandCapacity()
{
int newCapacity = Math.Max(_capacity * 2, 4);
T[] temp = new T[newCapacity];
Array.Copy(_elements, temp, _size);
_elements = temp;
_capacity = newCapacity;
}
public void EnsureCapacity(int minCapacity)
{
if (_capacity < minCapacity)
{
int newCapacity = Math.Max(_capacity * 2, minCapacity);
T[] temp = new T[newCapacity];
Array.Copy(_elements, temp, _size);
_elements = temp;
_capacity = newCapacity;
}
}
public T Peek()
{
if (_size == 0)
throw new InvalidOperationException("Queue is empty");
return _elements[0];
}
public T Dequeue()
{
if (_size == 0)
throw new InvalidOperationException("Queue is empty");
T result = _elements[0];
Swap(ref _elements[0], ref _elements[_size - 1]);
_size--;
ShiftDown();
return result;
}
public bool TryDequeue(out T result)
{
if (_size == 0)
{
result = default;
return false;
}
result = Dequeue();
return true;
}
public void Enqueue(T value)
{
if (_size == _capacity)
ExpandCapacity();
_elements[_size++] = value;
ShiftUp();
}
public bool Contains(T item)
{
for (int i = 0; i < _size; i++)
{
if (EqualityComparer<T>.Default.Equals(_elements[i], item))
return true;
}
return false;
}
public T[] ToArray()
{
T[] result = new T[_size];
Array.Copy(_elements, result, _size);
return result;
}
public void TrimExcess()
{
if (_size < _capacity * 0.9)
{
T[] temp = new T[_size];
Array.Copy(_elements, temp, _size);
_elements = temp;
_capacity = _size;
}
}
private void Swap(ref T a, ref T b)
{
T temp = a;
a = b;
b = temp;
}
public enum Comparator
{
less = -1,
equal = 0,
greater = 1
}
}
}

View File

@@ -0,0 +1,129 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace Convention
{
public static class WindowsKit
{
public static string current_initialDir = "";
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class OpenFileName
{
public int structSize = 0;
public IntPtr dlgOwner = IntPtr.Zero;
public IntPtr instance = IntPtr.Zero;
public string filter = null;
public string customFilter = null;
public int maxCustFilter = 0;
public int filterIndex = 0;
public string file = null;
public int maxFile = 0;
public string fileTitle = null;
public int maxFileTitle = 0;
public string initialDir = null;
public string title = null;
public int flags = 0;
public short fileOffset = 0;
public short fileExtension = 0;
public string defExt = null;
public IntPtr custData = IntPtr.Zero;
public IntPtr hook = IntPtr.Zero;
public string templateName = null;
public IntPtr reservedPtr = IntPtr.Zero;
public int reservedInt = 0;
public int flagsEx = 0;
}
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("Comdlg32.dll", SetLastError = true, ThrowOnUnmappableChar = true, CharSet = CharSet.Auto)]
public static extern bool GetSaveFileName([In, Out] OpenFileName ofn);
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lpbi);
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct BROWSEINFO
{
public IntPtr hwndOwner;
public IntPtr pidlRoot;
public string pszDisplayName;
public string lpszTitle;
public uint ulFlags;
public IntPtr lpfn;
public IntPtr lParam;
public int iImage;
}
public static string SelectFolder(string description = "请选择文件夹")
{
BROWSEINFO bi = new BROWSEINFO();
bi.lpszTitle = description;
bi.ulFlags = 0x00000040; // BIF_NEWDIALOGSTYLE
bi.hwndOwner = IntPtr.Zero;
IntPtr pidl = SHBrowseForFolder(ref bi);
if (pidl != IntPtr.Zero)
{
IntPtr pathPtr = Marshal.AllocHGlobal(260);
if (SHGetPathFromIDList(pidl, pathPtr))
{
string path = Marshal.PtrToStringAuto(pathPtr);
Marshal.FreeHGlobal(pathPtr);
current_initialDir = path;
return path;
}
Marshal.FreeHGlobal(pathPtr);
}
return null;
}
public static string[] SelectMultipleFiles(string filter = "所有文件|*.*", string title = "选择文件")
{
OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = filter.Replace("|", "\0") + "\0";
ofn.file = new string(new char[256]);
ofn.maxFile = ofn.file.Length;
ofn.fileTitle = new string(new char[64]);
ofn.maxFileTitle = ofn.fileTitle.Length;
ofn.initialDir = current_initialDir;
ofn.title = title;
ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008 | 0x00000200; // OFN_ALLOWMULTISELECT
if (GetOpenFileName(ofn))
{
current_initialDir = Path.GetDirectoryName(ofn.file);
return ofn.file.Split('\0');
}
return null;
}
public static string SaveFile(string filter = "所有文件|*.*", string title = "保存文件")
{
OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = filter.Replace("|", "\0") + "\0";
ofn.file = new string(new char[256]);
ofn.maxFile = ofn.file.Length;
ofn.fileTitle = new string(new char[64]);
ofn.maxFileTitle = ofn.fileTitle.Length;
ofn.initialDir = current_initialDir;
ofn.title = title;
ofn.flags = 0x00080000 | 0x00001000 | 0x00000800 | 0x00000008 | 0x00000002; // OFN_OVERWRITEPROMPT
if (GetSaveFileName(ofn))
{
current_initialDir = Path.GetDirectoryName(ofn.file);
return ofn.file;
}
return null;
}
}
}