【演算法】十一月陽光下的陰影面積

来源:https://www.cnblogs.com/lan80/archive/2023/11/03/17804412.html
-Advertisement-
Play Games

MongoDB+SignalR+Hangfire+Vue2+百度地圖實現GPS實時定位 一、實現效果 二、安裝MongoDB 可以自行參考菜鳥鏈接:MongoDB 教程 | 菜鳥教程 (runoob.com) 1.下載mongodb資料庫安裝包: 網盤鏈接:https://pan.baidu.com ...


十一月的陽光透過窗戶,照射在一位笑起來甜美、青春洋溢的女子的辦公桌上。小悅,一個總是以高馬尾造型亮相的軟體工程師,展現出她的幹練與活力。那烏黑亮麗的長髮輕盈飄動,仿佛在訴說著她的獨特魅力。她的眉眼如畫,那雙明亮的眼睛里閃爍著對知識的渴望和對技術挑戰的熱情。

這一天,她收到了一封來自醫院的郵件,郵件中提到的掃描設備技術更新問題讓她感到有些挑戰。然而,對於技術挑戰,小悅總是充滿了好奇心和熱情。她決定主動聯繫醫院,表達自己願意參與這個項目的意願。幸運的是,醫院方面很快回覆了她的郵件,並安排了一次電話會議。

在電話會議中,小悅與醫院的管理人員和相關領域的專家進行了交流。他們的聲音充滿了對新技術和新思維的渴望。小悅也意識到這次機會對於自己的事業發展可能是一個重大的突破。

不久之後,小悅成功加入了醫院方面的團隊。在團隊中,她發現了很多優秀的專家和工程師。其中有一位資深醫生對掃描設備的需求非常瞭解,而另一位工程師則對圖像處理演算法有深入的研究。小悅深知自己在這個團隊中擔任著關鍵的角色,必須充分發揮自己的優勢。

在團隊的合作中,小悅與大家建立了良好的合作關係。她不斷地與團隊成員溝通和交流,瞭解他們的需求和想法。她的聲音總是溫柔而自信,讓人感到安心和信任。同時,她也向團隊成員分享了自己的經驗和專業知識,為項目的進展做出了巨大的貢獻。

然而,隨著項目的深入,小悅逐漸發現了一些技術難題。其中最大的問題是如何計算陰影部分的面積並集。為瞭解決這個問題,她不斷地查閱文獻、研究演算法,並嘗試了多種方法。有時候,她會陷入深深的困境,甚至整晚都無法入睡。但是,她從未放棄過對這個問題的探索和解決。

經過一段時間的努力,小悅終於提出了一種有效的方法來計算陰影部分的面積並集。這個方法不僅得到了團隊的認可和支持,也成功地解決了項目中的一大難題。小悅的貢獻讓整個團隊都感到非常驚喜和敬佩。

在接下來的時間中,小悅和團隊繼續努力工作,終於成功地開發出了一款新的掃描設備程式設計。這款程式採用了小悅提出的陰影面積計算方法,有效地提高了掃描的準確性和效率。醫院方面對這款程式非常滿意,並決定將其投入使用。

在這個過程中,小悅學到了很多東西。她不僅在技術方面取得了突破和成長,還學會瞭如何與不同背景的人合作和溝通。她深刻地認識到人際關係的重要性以及如何利用人際關係來拓展自己的視野和能力。同時,她也體驗到了幫助他人的喜悅和成就感。


小悅面臨的問題是,醫學影像重建:醫學影像(如CT、MRI等)通常是由多個切片圖像組成的,這些圖像可能存在重疊或交叉的區域。矩形面積並集演算法可以用於計算這些圖像之間的重疊區域,從而實現準確的圖像重建和融合。

她需要開發一個名為Calculate的方法,該方法接受一個二維數組作為參數,其中每個子數組表示一個矩形的坐標。在這個例子中,三個矩形的坐標分別為[1,2,5,6]、[1,3,4,5]和[3,1,5,4]。並返回期望的面積並集。

每個矩形表示為:[x0,y0,x1,y1]
(x0,y0)-矩形左下角的坐標
(x1,y1)-矩形右上角的坐標

圖例(面積=18):


 演算法實現1:

 1 private class Rectangle // 定義一個名為Rectangle的私有類
 2 {
 3     public long x0; // 矩形的左邊界
 4     public long y0; // 矩形的底邊界
 5     public long x1; // 矩形的右邊界
 6     public long y1; // 矩形的頂邊界
 7     public bool ToDelete = false; // 標記是否需要刪除該矩形
 8 
 9     public Rectangle(long x0, long y0, long x1, long y1) // 構造函數,用於初始化矩形對象的邊界值
10     {
11         this.x0 = x0;
12         this.x1 = x1;
13         this.y0 = y0;
14         this.y1 = y1;
15     }
16 
17     public long S() // 計算矩形的面積
18     {
19         return (x1 - x0) * (y1 - y0);
20     }
21 
22     public bool IsInside(Rectangle r) // 判斷當前矩形是否完全包含另一個矩形r
23     {
24         return ((r.x0 >= x0) && (r.x1 <= x1) && (r.y0 >= y0) && (r.y1 <= y1)) ? true : false;
25     }
26 
27     public bool IsOutside(Rectangle r) // 判斷當前矩形是否完全在另一個矩形r的外部
28     {
29         return ((r.x0 >= x1) || (r.x1 <= x0) || (r.y0 >= y1) || (r.y1 <= y0)) ? true : false;
30     }
31 
32     public List<Rectangle> GetIntersection(Rectangle r) // 獲取當前矩形與另一個矩形r的相交部分
33     {
34         List<Rectangle> rests = new List<Rectangle>();
35         if (r.x0 < x0)
36             rests.Add(new Rectangle(r.x0, r.y0, x0, r.y1));
37         if (r.x1 > x1)
38             rests.Add(new Rectangle(x1, r.y0, r.x1, r.y1));
39         if (r.y0 < y0)
40             rests.Add(new Rectangle(Math.Max(r.x0, x0), r.y0, Math.Min(r.x1, x1), y0));
41         if (r.y1 > y1)
42             rests.Add(new Rectangle(Math.Max(r.x0, x0), y1, Math.Min(r.x1, x1), r.y1));
43         return rests;
44     }
45 }
46 
47 public static long Calculate(IEnumerable<int[]> rectangles) // 定義一個名為Calculate的靜態方法,用於計算矩形的最大面積
48 {
49     long maxS = 0; // 最大面積的初始值為0
50     List<Rectangle> lastRectangle = new List<Rectangle>(rectangles.Select(x => new Rectangle((long)x[0], (long)x[1], (long)x[2], (long)x[3]))); // 將傳入的矩形參數轉換為Rectangle對象,並添加到lastRectangle列表中
51     while (lastRectangle.Count > 0) // 當lastRectangle列表不為空時,進行迴圈
52     {
53         Rectangle top = lastRectangle.First(); // 獲取lastRectangle列表的第一個矩形對象
54         lastRectangle.Remove(top); // 從lastRectangle列表中移除該矩形對象
55         List<Rectangle> intersect = new List<Rectangle>() { top }; // 創建一個名為intersect的列表,初始值為包含top矩形對象的列表
56         var intersected = lastRectangle.Where(x => !x.IsOutside(top)); // 從lastRectangle列表中篩選出與top矩形相交的矩形對象,並存儲在intersected變數中
57         foreach (Rectangle r in intersected) // 遍歷intersected列表中的每個矩形對象
58         {
59             intersect.RemoveAll(x => r.IsInside(x)); // 從intersect列表中移除完全被r矩形包含的矩形對象
60             List<Rectangle> newIntersections = new List<Rectangle>();
61             foreach (Rectangle x in intersect) // 遍歷intersect列表中的每個矩形對象
62                 if (!r.IsOutside(x)) // 如果r矩形與x矩形相交
63                 {
64                     newIntersections.AddRange(r.GetIntersection(x)); // 獲取r矩形與x矩形的相交部分,並添加到newIntersections列表中
65                     x.ToDelete = true; // 標記x矩形需要刪除
66                 }
67             intersect.RemoveAll(x => x.ToDelete); // 從intersect列表中移除需要刪除的矩形對象
68             intersect.AddRange(newIntersections); // 將newIntersections列表中的矩形對象添加到intersect列表中
69             if (intersect.Count == 0) // 如果intersect列表為空,跳出迴圈
70                 break;
71         }
72         if (intersect.Count > 0) // 如果intersect列表不為空
73             maxS += intersect.Sum(x => x.S()); // 將intersect列表中每個矩形對象的面積相加,並累加到maxS變數中
74     }
75     return maxS; // 返回最大面積maxS
76 }

 首先,矩形的相交關係是指兩個矩形是否有共同的區域。我們可以通過判斷兩個矩形的邊界是否有重疊來確定它們是否相交。如果兩個矩形的邊界有重疊,則它們相交;否則,它們不相交。

其次,矩形的包含關係是指一個矩形是否完全包含另一個矩形。我們可以通過比較兩個矩形的邊界來確定包含關係。如果一個矩形的邊界完全包含在另一個矩形的邊界內部,則前者包含後者;否則,前者不包含後者。

在演算法中,我們首先將傳入的矩形參數轉換為Rectangle對象,並存儲在lastRectangle列表中。然後,通過迴圈處理lastRectangle列表中的矩形對象,找到與當前矩形相交的其他矩形對象,並計算它們的相交部分。

在處理每個矩形對象時,我們首先找到與當前矩形相交的矩形對象,並將它們存儲在intersected變數中。然後,我們遍歷intersected列表中的每個矩形對象,將完全被當前矩形包含的矩形對象從intersect列表中移除。接下來,對於與當前矩形相交的每個矩形對象,我們計算它們的相交部分,並將相交部分添加到intersect列表中。最後,我們將intersect列表中的矩形對象的面積相加,並累加到maxS變數中。

通過這種逐步計算矩形的相交部分,我們可以找到一組矩形的最大面積。這是因為我們通過不斷更新intersect列表來剔除已經被其他矩形完全包含的矩形,只保留與其他矩形相交的部分。最終,我們將intersect列表中的矩形對象的面積相加,得到這組矩形的最大面積。

這個演算法的數學原理基於矩形的幾何性質和集合運算的概念,通過對矩形的相交和包含關係進行處理,最終得到最大面積並集。 


 演算法實現2:

 1 struct Rect // 定義一個名為Rect的結構體
 2 {
 3     public int l, r, t, b; // 定義四個整型變數,分別表示矩形的左、右、上、下邊界
 4     public long area => (long)(r - l) * (t - b); // 定義一個名為area的只讀屬性,表示矩形的面積
 5     public bool exist => l < r && b < t; // 定義一個名為exist的只讀屬性,表示矩形是否存在
 6 
 7     public static Rect Create(params int[] c) => // 定義一個名為Create的靜態方法,用於創建一個新的Rect對象
 8         new Rect() { l = c[0], b = c[1], r = c[2], t = c[3] };
 9 
10     public bool intersects(Rect rc, out Rect result) => // 定義一個名為intersects的方法,用於判斷兩個矩形是否相交,並返回相交部分的矩形對象
11         (result = Create(
12             Math.Max(l, rc.l), Math.Max(b, rc.b),
13             Math.Min(r, rc.r), Math.Min(t, rc.t)))
14         .exist;
15 
16     public Rect[] octants(int n = int.MinValue, int p = int.MaxValue) => // 定義一個名為octants的方法,用於將當前矩形分成八個象限,並返回八個象限的矩形對象數組
17         new [] {
18             Create(n, n, l, b),
19             Create(n, b, l, t),
20             Create(n, t, l, p),
21             Create(l, t, r, p),
22             Create(r, t, p, p),
23             Create(r, b, p, t),
24             Create(r, n, p, b),
25             Create(l, n, r, b)
26         };
27 }
28 
29 class OctTreeNode // 定義一個名為OctTreeNode的類
30 {
31     Rect          origin; // 定義一個名為origin的Rect對象,表示當前節點所代表的矩形
32     Rect[]        oct_bounds; // 定義一個名為oct_bounds的Rect對象數組,表示當前節點所代表的矩形被分成的八個象限
33     OctTreeNode[] oct_values; // 定義一個名為oct_values的OctTreeNode對象數組,表示當前節點所代表的矩形被分成的八個象限所代表的子節點
34 
35     public OctTreeNode(Rect rc) // 定義一個構造函數,用於創建一個新的OctTreeNode對象
36     {
37         origin = rc; // 將傳入的Rect對象賦值給origin變數
38         oct_bounds = rc.octants(); // 將當前矩形分成八個象限,並賦值給oct_bounds變數
39         oct_values = new OctTreeNode[8]; // 創建一個長度為8的OctTreeNode對象數組,並賦值給oct_values變數
40     }
41 
42     public void insert(Rect rc) // 定義一個名為insert的方法,用於向當前節點插入一個新的矩形對象
43     {
44         for (int i = 0; i < 8; i++) // 遍歷oct_bounds數組中的每個矩形對象
45         {
46             if (oct_bounds[i].intersects(rc, out var part)) // 如果當前矩形與遍歷到的矩形相交
47             {
48                 oct_values[i] ?.  insert(part); // 如果oct_values數組中第i個元素不為null,則遞歸調用insert方法,將part矩形插入到oct_values數組中第i個元素所代表的子節點中
49                 oct_values[i] ??= new OctTreeNode(part); // 如果oct_values數組中第i個元素為null,則創建一個新的OctTreeNode對象,並賦值給oct_values數組中第i個元素
50             }
51         }
52     }
53 
54     public long area => origin.area + // 定義一個名為area的只讀屬性,表示當前節點所代表的矩形的面積加上所有子節點所代表的矩形的面積之和
55         oct_values.Sum(v => v?.area ?? 0); // 遍歷oct_values數組中的每個元素,如果元素不為null,則獲取它所代表的矩形的面積,否則返回0
56 }
57 
58 public static class Edm // 定義一個名為Edm的靜態類
59 {
60     public static long Calculate(IEnumerable<int[]> rc) // 定義一個名為Calculate的靜態方法,用於計算一組矩形的最大面積
61     {
62         var en = rc.Select(Rect.Create).GetEnumerator(); // 將傳入的矩形參數轉換為Rect對象,並獲取一個枚舉器
63         if (!en.MoveNext()) return 0; // 如果枚舉器沒有下一個元素,則直接返回0
64 
65         var tree = new OctTreeNode(en.Current); // 創建一個新的OctTreeNode對象,並將枚舉器的第一個元素作為參數傳入
66         while (en.MoveNext()) tree.insert(en.Current); // 遍歷枚舉器中的每個元素,並將它們插入到tree中
67         return tree.area; // 返回tree所代表的矩形的面積
68     }
69 }

 這段代碼實現了一個八叉樹演算法,用於計算一組矩形的最大面積。

八叉樹演算法是一種經典的數據結構和演算法,其歷史可以追溯到20世紀60年代。它最早被用於電腦圖形學和電腦視覺領域,用於處理空間分割和區域查詢等問題。

八叉樹最早由法國電腦科學家Frits van der Hoeven在1966年引入,用於在電腦圖形學中進行空間分割和區域查詢。八叉樹的名字來源於其樹狀結構,每個節點有八個子節點,對應於三維空間中的八個象限。

隨後,八叉樹在電腦視覺領域得到廣泛應用,用於處理圖像和空間數據。例如,八叉樹可以用於圖像壓縮、圖像搜索、碰撞檢測等應用中。

隨著電腦硬體和演算法的發展,八叉樹的變種和改進也被提出。例如,四叉樹是八叉樹的二維版本,用於處理二維空間數據。此外,還有基於八叉樹的自適應分割方法和多解析度表示方法等。

八叉樹演算法的應用領域不僅限於電腦圖形學和電腦視覺,還可以用於地理信息系統、醫學圖像處理、物理模擬等領域。它提供了一種高效的數據結構和演算法,可以用於處理多維空間數據和進行空間查詢。

  1. Rect結構體表示一個矩形對象,其中包含矩形的左、右、上、下邊界,以及計算矩形面積和判斷矩形是否存在的屬性。

  2. Rect結構體還定義了一個intersects方法,用於判斷兩個矩形是否相交,並返回相交部分的矩形對象。

  3. Rect結構體還定義了一個octants方法,用於將當前矩形分成八個象限,並返回八個象限的矩形對象數組。

  4. OctTreeNode類表示一個八叉樹節點,每個節點代表一個矩形。該類包含一個origin變數表示當前節點所代表的矩形,以及一個oct_bounds數組表示當前節點所代表的矩形被分成的八個象限,以及一個oct_values數組表示八個象限所代表的子節點。

  5. OctTreeNode類定義了一個insert方法,用於向當前節點插入一個新的矩形對象。該方法通過遍歷八個象限的矩形對象,判斷當前矩形與遍歷到的矩形是否相交,如果相交則遞歸調用insert方法將相交部分的矩形插入到對應的子節點中。

  6. OctTreeNode類還定義了一個area屬性,表示當前節點所代表的矩形的面積加上所有子節點所代表的矩形的面積之和。

  7. Edm靜態類定義了一個Calculate方法,用於計算一組矩形的最大面積。該方法首先將傳入的矩形參數轉換為Rect對象,並創建一個八叉樹節點。然後,遍歷矩形對象並將它們插入到八叉樹中。最後,返回八叉樹所代表的矩形的面積作為結果。

這個演算法的數學原理基於矩形的幾何性質和八叉樹的概念,通過構建八叉樹來處理矩形的相交和包含關係,最終得到一組矩形的最大面積並集。 


演算法2中有些簡寫的cSharp語法,解釋如下:

 1 //1.這段代碼使用了C#語言的Lambda表達式和對象初始化器。Lambda表達式用於定義一個匿名方法,而對象初始化器用於在創建對象的同時對其屬性進行初始化。
 2 public static Rect Create(params int[] c) =>
 3             new Rect() { l = c[0], b = c[1], r = c[2], t = c[3] };
 4 
 5 //這段代碼定義了一個名為Create的靜態方法,其目的是創建一個矩形對象。該方法接受一個可變長度的整數數組作為參數,數組中的元素按照特定的順序表示矩形的左邊界、底邊界、右邊界和頂邊界。
 6 //以下是另一種常用寫法:
 7 public static Rect Create(params int[] c)
 8 {
 9     int left = c[0];
10     int bottom = c[1];
11     int right = c[2];
12     int top = c[3];
13 
14     Rect rect = new Rect();
15     rect.l = left;
16     rect.b = bottom;
17     rect.r = right;
18     rect.t = top;
19 
20     return rect;
21 }
22 
23 //2.同一
24  public bool intersects(Rect rc, out Rect result) =>
25             (result = Create(
26                 Math.Max(l, rc.l), Math.Max(b, rc.b),
27                 Math.Min(r, rc.r), Math.Min(t, rc.t)))
28             .exist;
29 
30 //常用寫法:
31 public bool Intersects(Rect rc, out Rect result)
32 {
33     int left = Math.Max(l, rc.l);
34     int bottom = Math.Max(b, rc.b);
35     int right = Math.Min(r, rc.r);
36     int top = Math.Min(t, rc.t);
37 
38     result = Create(left, bottom, right, top);
39 
40     return result.exist;
41 }
42 /*
43 在這個寫法中,首先根據兩個矩形的左邊界、底邊界、右邊界和頂邊界的最大值和最小值,分別計算出相交部分的矩形的左邊界、底邊界、右邊界和頂邊界。
44 
45 然後,使用這些計算結果調用Create方法創建一個新的矩形對象,並將其賦值給result參數。
46 
47 最後,返回新創建的矩形對象的exist屬性,表示兩個矩形是否相交。
48 
49 這個寫法與原始代碼的功能相同,但使用了更加明確的變數名和更加傳統的語法,使其更容易理解。*/

 演算法2和演算法1都是用於計算矩形的面積交集的實現,但它們使用了不同的數據結構和演算法。

演算法1使用了一個二維數組來表示每個點的覆蓋情況,並使用掃描線演算法來計算矩形的面積交集。這個演算法的優點是實現簡單,但需要額外的空間來存儲覆蓋情況,並且在處理大量矩形時可能會變得非常慢。

相比之下,演算法2使用了八叉樹的數據結構來表示矩形,並使用遞歸的方式來插入和查詢矩形。這個演算法的優點是可以高效地處理大量矩形,並且可以快速地計算矩形的面積交集。但缺點是實現相對複雜,需要額外的空間來存儲八叉樹節點,而且在處理高維數據時可能不太適用。

總的來說,這兩個演算法都有各自的優缺點,可以根據具體情況選擇適合的演算法。如果處理的數據量不是很大,或者需要實現的演算法比較簡單,那麼可以選擇演算法1;如果處理的數據量比較大,或者需要高效地計算矩形的面積交集,那麼可以選擇演算法2。


測試用例:

  1 namespace Solution {
  2   using NUnit.Framework;
  3   using System;
  4   using System.Collections.Generic;
  5   using System.Linq;
  6   using static NUnit.Framework.Assert;
  7     
  8 
  9   public class RandSort
 10   {
 11       public static IEnumerable<int[]> Shuffle(List<int[]> recs)
 12       {
 13         var rnd = new Random();
 14         var order = new List<double>();
 15         for (int i = 0; i < recs.Count; i++) {
 16             order.Add(rnd.NextDouble());
 17         }
 18         var orderArray = order.ToArray();
 19         var recsArray = recs.ToArray();
 20         Array.Sort(orderArray, recsArray);
 21         return recsArray;
 22       }
 23   }
 24 
 25   [TestFixture]
 26   public class BasicTests
 27   {
 28     [Test]
 29     public void ZeroRectangles()
 30     {
 31       AreEqual(0, Edm.Calculate(Enumerable.Empty<int[]>()));
 32     }
 33 
 34     [Test]
 35     public void OneRectangle()
 36     {
 37       AreEqual(1, Edm.Calculate(new [] { new [] {0,0,1,1}}));
 38     }
 39  
 40     [Test]
 41     public void OneRectangleV2()
 42     {
 43       AreEqual(22, Edm.Calculate(new [] { new [] {0, 4, 11, 6}}));
 44     }
 45   
 46     [Test]
 47     public void TwoRectangles()
 48     {
 49       AreEqual(2, Edm.Calculate(new [] { new [] {0,0,1,1}, new [] {1,1,2,2}}));
 50     }
 51 
 52     [Test]
 53     public void TwoRectanglesV2()
 54     {
 55       AreEqual(4, Edm.Calculate(new [] { new [] {0,0,1,1}, new [] {0,0,2,2}}));
 56     }
 57 
 58     [Test]
 59     public void ThreeRectangles()
 60     {
 61       AreEqual(36, Edm.Calculate(new [] { new [] {3,3,8,5}, new [] {6,3,8,9}, new [] {11,6,14,12}}));
 62     }
 63   }
 64   
 65   [TestFixture]
 66   public class ExpandedTests
 67   {
 68     [Test]
 69     public void RectanglesWithoutIntersections()
 70     {
 71       var recs = new [] {
 72         new [] { 1, 1, 2, 2 },
 73         new [] { 2, 2, 3, 3 },
 74         new [] { 3, 3, 4, 4 },
 75         new [] { 4, 4, 5, 5 },
 76         new [] { 2, 1, 3, 2 }
 77       }; 
 78     
 79       AreEqual(5, Edm.Calculate(recs));
 80     }
 81     
 82     
 83     [Test]
 84     public 
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在Go編程語言中處理數據時,經常會遇到數組和切片。這兩者是不同的數據結構,有各自的特性和用途。本文將對Go中的數組和切片進行比較,以幫助大家更好地理解它們。 1. 長度不同 一個主要的區別是長度。在Go中,數組是具有固定長度的數據結構,一旦創建,其大小不可更改。相比之下,切片具有動態大小,可以在運行 ...
  • 集合類不安全 List不安全 單線程情況下集合類和很多其他的類都是安全的,因為同一時間只有一個線程在對他們進行修改,但是如果是多線程情況下,那麼集合類就不一定是安全的,可能會出現一條線程正在修改的同時另一條線程啟動來對這個集合進行修改,這種情況下就會導致發生併發修改異常(在jdk11的環境下多次測試 ...
  • Spring Boot 是一種廣泛使用且非常流行的企業級高性能框架。以下是一些最佳實踐和一些技巧,我們可以使用它們來改進 Spring Boot 應用程式並使其更加高效。這篇文章會有點長,完整讀完文章需要一些時間。 1.正確的包目錄風格 正確的包目錄將有助於輕鬆理解代碼和應用程式的流程。 我們可以使 ...
  • 傅里葉變換是一種數學變換,它可以將一個函數或信號轉換為另一個函數或信號,它可以將時域信號轉換為頻域信號,也可以將頻域信號轉換為時域信號。在很多的領域都有廣泛的應用,例如信號處理、通信、圖像處理、電腦科學、物理學、生物學等。 它最大的功能是能夠分析和提取信號的特征,將複雜的信號分解為簡單的信號。有人 ...
  • 一、前言 在現代軟體開發中,事務處理是必不可少的一部分。當多個操作需要作為一個整體來執行時,事務可以確保數據的完整性和一致性,並避免出現異常和錯誤情況。在SpringBoot框架中,我們可以使用聲明式事務和編程式事務來管理事務處理。其中事務的坑也是不少,比較常見的就是事務失效,大家可以看看!後面小編 ...
  • 一個數據包在HTP的旅游中的暢游之旅,帶你瞭解HTTPS/HTTP2,及反向代理處理,經歷壓縮限流等奇特的歷險記。 ...
  • PDF 文件可以包含文本、圖片及各種媒體元素,但如果文件太大則會影響傳輸效果同時也會占用過多磁碟空間。通過壓縮PDF文件,能夠有效減小文件大小,從而提高傳輸效率並節省存儲空間。想要通過C#代碼快速有效地壓縮 PDF 文件,下麵是實現思路: 在 C# 中壓縮 PDF 1、在VS中使用 NuGet包管理 ...
  • 最近重構並精簡了Dapper.Lite,然後把不依賴Dapper的版本LiteSql也重構了一下,和Dapper.Lite保持一致。感覺這兩款ORM基本完工,自薦一下。 .NET的ORM雖多,堪用的不多,何為堪用,EF是官方的,質量高,堪用。Dapper用戶量大,現在BUG基本改的差不多了,也基本不 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...