演算法(第四版)C#題解——1.4

来源:http://www.cnblogs.com/ikesnowy/archive/2017/09/02/7467994.html
-Advertisement-
Play Games

寫在前面整個項目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp這一節內容可能會用到的庫文件有 Measurement 和 TestCase,同樣在 Github 上可以找到。善用 Ctrl + F... ...


寫在前面

整個項目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp

這一節內容可能會用到的庫文件有 Measurement 和 TestCase,同樣在 Github 上可以找到。

善用 Ctrl + F 查找題目。

習題&題解

1.4.1

題目

證明從 N 個數中取三個整數的不同組合總數為 N(N - 1)(N - 2) / 6。

解答

即為證明組合計算公式:

C(N, 3)

= N! / [(N - 3)! × 3!]
= [(N - 2) * (N - 1) * N] / 3!
= N(N - 1)(N - 2) / 6

顯然 N 必須大於等於 3。
N = 3 時公式正確,只有一種組合。
N = 4 時公式正確,只有四種組合。


擴展到 N+1 個數,將 N = N + 1 代入,可得:
(N + 1)N(N - 1) / 6
N + 1 個數能組成的三位數組合可以這樣理解
前 N 個數中取三個數的所有組合 +多出的一個數和前 N 個數中的任意取兩個數的所有組合
即為 N(N-1)(N - 2) / 6 + C(N, 2)
變形後即為(N + 1)N(N - 1) / 6

得證。


1.4.2

題目

修改 ThreeSum,正確處理兩個較大 int 值相加可能溢出的情況。

解答

將 a[i] + a[j] + a[k] 改為 (long)a[i] + a[j] + a[k] 即可。

此時整個式子將按照精度最高(也就是 long)的標準計算。

long.MaxValue = 9223372036854775807 > int.MaxValue * 3 = 6442450941

代碼
namespace Measurement
{
    /// <summary>
    /// 用暴力方法尋找數組中和為零的三元組。
    /// </summary>
    public static class ThreeSum
    {
        /// <summary>
        /// 輸出所有和為零的三元組。
        /// </summary>
        /// <param name="a">輸入數組。</param>
        public static void PrintAll(int[] a)
        {
            int n = a.Length;
            for (int i = 0; i < n; ++i)
            {
                for (int j = i + 1; j < n; ++j)
                {
                    for (int k = j + 1; k < n; ++k)
                    {
                        if ((long)a[i] + a[j] + a[k] == 0)
                        {
                            Console.WriteLine($"{a[i]} + {a[j]} + {a[k]}");
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 計算和為零的三元組的數量。
        /// </summary>
        /// <param name="a">輸入數組。</param>
        /// <returns></returns>
        public static int Count(int[] a)
        {
            int n = a.Length;
            int count = 0;
            for (int i = 0; i < n; ++i)
            {
                for (int j = i + 1; j < n; ++j)
                {
                    for (int k = j + 1; k < n; ++k)
                    {
                        if ((long)a[i] + a[j] + a[k] == 0)
                        {
                            count++;
                        }
                    }
                }
            }
            return count;
        }
    }
}


1.4.3

題目

修改 DoublingTest,使用 StdDraw 產生類似於正文中的標準圖像和對數圖像,
根據需要調整比例使圖像總能夠充滿視窗的大部分區域。

解答

見代碼,這裡貼出繪圖函數,窗體只是在得到測試結果之後簡單調用以下這兩個函數。

代碼
public static void PaintLinear(double[] testResult)
        {
            //新建一個繪圖視窗
            Form2 linear = new Form2();
            linear.Show();
            //新建畫布
            Graphics canvas = linear.CreateGraphics();
            //獲取視窗區域
            Rectangle rect = linear.ClientRectangle;
            //計算單位長度(十等分)
            int unitY = rect.Height / 10;
            int unitX = rect.Width / 10;
            //獲取中心區域(上下左右增加 10% 的內補)
            Rectangle center = new Rectangle(rect.X + unitX, rect.Y + unitY, unitX * 8, unitY * 8);
            //繪製坐標系
            canvas.DrawLine(Pens.Black, center.X, center.Y, center.X, center.Y + center.Height);
            canvas.DrawLine(Pens.Black, center.X, center.Y + center.Height, center.X + center.Width, center.Y + center.Height);
            //對 X 軸 10 等分,對 Y 軸 10 等分
            int xaxisUnit = center.Width / 10;
            int yaxisUnit = center.Height / 10;
            //標記 X 軸坐標值
            for (int i = 1; i <= 8; i += i)
            {
                canvas.DrawString(i + "N", linear.Font, Brushes.Black, center.X + i * xaxisUnit, center.Y + center.Height);
            }
            //反轉坐標系
            canvas.TranslateTransform(0, linear.ClientRectangle.Height);
            canvas.ScaleTransform(1, -1);
            //計算單位長度
            double Unit = center.Height / testResult[3];
            //標記
            PointF[] result = new PointF[4];
            for (int i = 0, j = 1; i < 4 && j <= 8; ++i, j += j)
            {
                result[i] = new PointF(center.X + j * xaxisUnit, (float)(center.Y + Unit * testResult[i]));
            }
            //鏈接
            canvas.DrawLines(Pens.Black, result);

            canvas.Dispose();
        }

        public static void PaintLogarithm(double[] testResult)
        {
            //新建一個繪圖視窗
            Form2 log = new Form2();
            log.Show();
            //新建畫布
            Graphics canvas = log.CreateGraphics();
            //獲取視窗區域
            Rectangle rect = log.ClientRectangle;
            //計算單位長度(十等分)
            int unitY = rect.Height / 10;
            int unitX = rect.Width / 10;
            //獲取中心區域(上下左右增加 10% 的內補)
            Rectangle center = new Rectangle(rect.X + unitX, rect.Y + unitY, unitX * 8, unitY * 8);
            //繪製坐標系
            canvas.DrawLine(Pens.Black, center.X, center.Y, center.X, center.Y + center.Height);
            canvas.DrawLine(Pens.Black, center.X, center.Y + center.Height, center.X + center.Width, center.Y + center.Height);
            //對 X 軸 10 等分,對 Y 軸 10 等分
            int xaxisUnit = center.Width / 10;
            int yaxisUnit = center.Height / 10;
            //標記 X 軸坐標值
            for (int i = 1; i <= 8; i += i)
            {
                canvas.DrawString(i + "N", log.Font, Brushes.Black, center.X + i * xaxisUnit, center.Y + center.Height);
            }
            //反轉坐標系
            canvas.TranslateTransform(0, log.ClientRectangle.Height);
            canvas.ScaleTransform(1, -1);
            //計算單位長度
            double Unit = center.Height / testResult[3];
            //標記
            PointF[] result = new PointF[4];
            for (int i = 0, j = 1; i < 4 && j <= 8; ++i, j += j)
            {
                result[i] = new PointF(center.X + j * xaxisUnit, (float)(center.Y + Unit * testResult[i]));
            }
            //鏈接
            canvas.DrawLines(Pens.Black, result);
            canvas.Dispose();
        }


1.4.4

題目

參照表 1.4.4 為 TwoSum 建立一張類似的表格。

解答

image

代碼分塊↑

時間分析↓

1.4.4


1.4.5

題目

給出下麵這些量的近似:
a. N + 1
b. 1 + 1/N
c. (1 + 1/N)(1 + 2/N)
d. 2N^3 - 15N^2 + N
e. lg(2N) / lgN
f. lg(N^2 + 1) / lgN
g. N^100 / 2^N

解答

類似於取極限的做法。

a. N

b. 1

c. 1

d. 2N3

e. 1

f. 2

g. N100 


1.4.6

題目

給出以下代碼段的運行時間的增長數量級(作為 N 的函數)。

a.

int sum = 0;
for (int n = N; n > 0; n /= 2)
    for (int i = 0; i < n; i++)
        sum++;

b.

int sum = 0;
for (int i = 1; i < N; i *= 2)
    for (int j = 0; j < i; j++)
        sum++;

c.

int sum = 0;
for (int i = 1; i < N; i *= 2)
    for (int j = 0; j < N; j++)
        sum++;


解答

a. N + N/2 + N/4 + … = ~2N,線性。

b. 1 + 2 + 4 + … = ~2N,線性。

c. logN * N,線性對數。


1.4.7

題目

以統計涉及輸入數字的算數操作(和比較)的成本模型分析 ThreeSum。

解答

最外層迴圈進行了 N 次比較。

次外層迴圈進行了 N^2 次比較。

最裡層迴圈進行了 N^3 次比較。

內部 if 語句進行了 N^3 次比較。

if 內部進行了 N(N-1) 次加法。

加起來,~2N^3。


1.4.8

題目

編寫一個程式,計算輸入文件中相等的整數對的數量。
如果你的第一個程式是平方級別的,
請繼續思考並用 Array.sort() 給出一個線性對數級別的解答。

解答

平方級別:直接二層迴圈遍歷一遍。

線性對數:只遍歷一遍數組,在遍歷過程中用二分查找確認在剩餘數組中是否有相等的整數。

代碼
/// <summary>
        /// 暴力查找數組中相等的整數對。
        /// </summary>
        /// <param name="a">需要查找的數組。</param>
        /// <returns></returns>
        static int CountEqual(int[] a)
        {
            int n = a.Length;
            int count = 0;
            for (int i = 0; i < n; ++i)
            {
                for (int j = i + 1; j < n; ++j)
                {
                    if (a[i] == a[j])
                        count++;
                }
            }

            return count;
        }

暴力演算法↑

二分查找演算法↓

/// <summary>
        /// 利用二分查找進行優化的查找相等整數對演算法。
        /// </summary>
        /// <param name="a">需要查找的數組。</param>
        /// <returns></returns>
        static int CountEqualLog(int[] a)
        {
            int n = a.Length;
            int count = 0;
            Array.Sort(a);
            for (int i = 0; i < n; ++i)
            {
                if (BinarySearch.Rank(a[i], a, i + 1, a.Length - 1) != -1)
                {
                    count++;
                }
            }
            return count;
        }


1.4.9

題目

已知由倍率實驗可得某個程式的時間倍率為 2^b 且問題規模為 N0 時程式運行時間為 T,
給出一個公式預測該程式在處理規模為 N 的問題時所需的運行時間。

解答

image



1.4.10

題目

修改二分查找演算法,使之總是返回和被查找的鍵匹配的索引最小的元素。
(但仍能夠保證對數級別的運行時間)

解答

修改二分查找的結束條件,找到後仍然向左側尋找,如果還能找到更小的,則返回較小的下標;否則返回當前下標。

代碼
namespace _1._4._10
{
    /// <summary>
    /// 二分查找。
    /// </summary>
    public class BinarySearch
    {
        /// <summary>
        /// 用遞歸方法進行二分查找。
        /// </summary>
        /// <param name="key">關鍵字。</param>
        /// <param name="a">查找範圍。</param>
        /// <param name="lo">查找的起始下標。</param>
        /// <param name="hi">查找的結束下標。</param>
        /// <returns>返回下標,如果沒有找到則返回 -1。</returns>
        public static int Rank(int key, int[] a, int lo, int hi)
        {
            if (hi < lo)
                return -1;
            int mid = (hi - lo) / 2 + lo;
            if (a[mid] == key)
            {
                int mini = Rank(key, a, lo, mid - 1);
                if (mini != -1)
                    return mini;
                return mid;
            }
            else if (a[mid] < key)
            {
                return Rank(key, a, mid + 1, hi);
            }
            else
            {
                return Rank(key, a, lo, mid - 1);
            }
        }
    }
}


1.4.11

題目

為 StaticSETofInts (請見表 1.2.15) 添加一個實例方法 howMany(),
找出給定鍵的出現次數且在最壞情況下所需的運行時間應該和 log(N) 成正比。

解答

這裡給出官網上的 Java 實現:StaticSETofInts.java

howMany() 可以用二分查找實現,在找到一個值後繼續向兩側查找,最後返回找到的次數。

代碼
using System;

namespace Measurement
{
    /// <summary>
    /// 有序數組,能夠快速查找並自動維護其中的順序。
    /// </summary>
    public class StaticSETofInts
    {
        private int[] a;

        /// <summary>
        /// 用一個數組初始化有序數組。
        /// </summary>
        /// <param name="keys">源數組。</param>
        public StaticSETofInts(int[] keys)
        {
            this.a = new int[keys.Length];
            for (int i = 0; i < keys.Length; ++i)
            {
                this.a[i] = keys[i];
            }
            Array.Sort(this.a);
        }

        /// <summary>
        /// 檢查數組中是否存在指定元素。
        /// </summary>
        /// <param name="key">要查找的值。</param>
        /// <returns>存在則返回 true,否則返回 false。</returns>
        public bool Contains(int key)
        {
            return Rank(key, 0, this.a.Length - 1) != -1;
        }

        /// <summary>
        /// 返回某個元素在數組中存在的數量。
        /// </summary>
        /// <param name="key">關鍵值。</param>
        /// <returns>返回某個元素在數組中存在的數量。</returns>
        public int HowMany(int key)
        {
            int hi = this.a.Length - 1;
            int lo = 0;
            
            return HowMany(key, lo, hi);
        }

        /// <summary>
        /// 返回某個元素在數組中存在的數量。
        /// </summary>
        /// <param name="key">關鍵值。</param>
        /// <param name="lo">查找起始下標。</param>
        /// <param name="hi">查找結束下標。</param>
        /// <returns>返回某個元素在數組中存在的數量。</returns>
        private int HowMany(int key, int lo, int hi)
        {
            int mid = Rank(key, lo, hi);
            if (mid == -1)
                return 0;
            else
            {
                return 1 + HowMany(key, lo, mid - 1) + HowMany(key, mid + 1, hi);
            }
        }

        /// <summary>
        /// 二分查找。
        /// </summary>
        /// <param name="key">關鍵值。</param>
        /// <param name="lo">查找的起始下標。</param>
        /// <param name="hi">查找的結束下標。</param>
        /// <returns>返回關鍵值的下標,如果不存在則返回 -1。</returns>
        public int Rank(int key, int lo, int hi)
        {
            while (lo <= hi)
            {
                int mid = (hi - lo) / 2 + lo;
                if (key < this.a[mid])
                    hi = mid - 1;
                else if (key > this.a[mid])
                    lo = mid + 1;
                else
                    return mid;
            }
            return -1;
        }
    }
}


1.4.12

題目

編寫一個程式,有序列印給定的兩個有序數組(含有 N 個 int 值) 中的所有公共元素,
程式在最壞情況下所需的運行時間應該和 N 成正比。

解答

由於兩個數組都是有序的,可以同時進行比較。

設 i, j 分別為兩個數組的下標。
如果 a[i] == a[j],i 和 j 都向後移動一位。
如果 a[i] != a[j],比較小的那個向後移動一位。
迴圈直到某個數組遍歷完畢。

這樣最後的時間複雜度 ~2N

代碼
using System;

namespace _1._4._12
{
    /*
     * 1.4.12
     * 
     * 編寫一個程式,有序列印給定的兩個有序數組(含有 N 個 int 值) 中的所有公共元素,
     * 程式在最壞情況下所需的運行時間應該和 N 成正比。
     * 
     */
    class Program
    {
        static void Main(string[] args)
        {
            int[] a = new int[4] { 2, 3, 4, 10 };
            int[] b = new int[6] { 1, 3, 3, 5, 10, 11 };

            //2N 次數組訪問,數組 a 和數組 b 各遍歷一遍
            for (int i = 0, j = 0; i < a.Length && j < b.Length; )
            {
                if (a[i] < b[j])
                {
                    i++;
                }
                else if (a[i] > b[j])
                {
                    j++;
                }
                else
                {
                    Console.WriteLine($"Common Element:{a[i]}, First index: (a[{i}], b[{j}])");
                    i++;
                    j++;
                }
            }

        }
    }
}


1.4.13

題目

根據正文中的假設分別給出表示以下數據類型的一個對象所需的記憶體量:
a. Accumulator
b. Transaction
c. FixedCapacityStackOfStrings,其容量為 C 且含有 N 個元素。
d. Point2D
e. Interval1D
f. Interval2D
g. Double

解答

對象的固定開銷用 Object 表示。

a. Accumulator

使用 1.2.4.3 節給出的實現。
= int * 1 + double + Object * 1

= 4 * 1 + 8 + 16 * 1 = 32

b. Transaction

= string * 1 + Date * 1 + double * 1 + Object * 1

= (40 + 16 + 4 + 4 + 2N) * 1 + (8 + 32) * 1 + 8 * 1 + 16 * 1

= 128 + 2N

c. FixedCapacityStackOfStrings

= string[] * 1 + string * N + int * 1 +  Object * 1

= 24 * 1 + N * (64 + 2C) + 4 * 1 + 16 * 1

= N * (64 + 2C) + 44

= N * (64 + 2C) + 48(填充)

d.Point2D

= double * 2 + Object * 1

= 8 * 2 + 16 * 1

= 32

e.Interval1D

= double * 2 + Object * 1

= 8 * 2 + 16 * 1

= 32

f.Interval2D

= Interval1D * 2 + Object * 1

= (8 + 24) * 2 + 16 * 1

= 80

g.Double

= double * 1 + Object * 1

= 8 * 1 + 16 * 1

= 24


1.4.14

題目

4-sum。

為 4-sum 設計一個演算法。

解答

這裡給出暴力方法,將最內側迴圈換成二分查找即為優化版本。

代碼
using System;

namespace Measurement
{
    /// <summary>
    /// 用暴力方法查找數組中和為零的四元組。
    /// </summary>
    public static class FourSum
    {
        /// <summary>
        /// 輸出數組中所有和為 0 的四元組。
        /// </summary>
        /// <param name="a">包含所有元素的數組。</param>
        public static void PrintAll(long[] a)
        {
            int N = a.Length;
            for (int i = 0; i < N; ++i)
            {
                for (int j = i + 1; j < N; ++j)
                {
                    for (int k = j + 1; k < N; ++k)
                    {
                        for (int l = k + 1; l < N; ++l)
                        {
                            if (a[i] + a[j] + a[k] + a[l] == 0)
                            {
                                Console.WriteLine($"{a[i]} + {a[j]} + {a[k]} + {a[l]} = 0");
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 計算和為零的四元組的數量。
        /// </summary>
        /// <param name="a">包含所有元素的數組。</param>
        /// <returns></returns>
        public static int Count(long[] a)
        {
            int N = a.Length;
            int cnt = 0;

            for (int i = 0; i < N; ++i)
            {
                for (int j = i + 1; j < N; ++j)
                {
                    for (int k = j + 1; k < N; ++k)
                    {
                        for (int l = k + 1; l < N; ++l)
                        {
                            if (a[i] + a[j] + a[k] + a[l] == 0)
                            {
                                cnt++;
                            }
                        }
                    }
                }
            }

            return cnt;
        }
    }
}


1.4.15

題目

快速 3-sum。
作為熱身,使用一個線性級別的演算法
(而非基於二分查找的線性對數級別的演算法)
實現 TwoSumFaster 來計算已排序的數組中和為 0 的整數對的數量。
用相同的思想為 3-sum 問題給出一個平方級別的演算法。

解答

由於數組已經排序(從小到大),負數在左側,正數在右側。
TwoSumFaster
設最左側下標為 lo,最右側下標為 hi。
如果 a[lo] + a[hi] > 0, 說明正數太大,hi--。
如果 a[lo] + a[hi] < 0,說明負數太小,lo++。
否則就找到了一對和為零的整數對,lo++, hi--。

ThreeSumFaster
對於數組中的每一個數 a,ThreeSum 問題就等於求剩餘數組中所有和為 -a 的 TwoSum 問題。
只要在 TwoSumFaster 外層再套一個迴圈即可。

代碼
/// <summary>
        /// TwoSum 的快速實現。(線性級別)
        /// </summary>
        /// <param name="a">需要查找的數組範圍。</param>
        /// <returns>數組中和為零的整數對數量。</returns>
        static int TwoSumFaster(int[] a)
        {
            int i = 0;
            int j = a.Length - 1;
            int count = 0;
            while (i != j)
            {
                if (a[i] + a[j] == 0)
                {
                    count++;
                    i++;
                    j--;
                }
                else if (a[i] + a[j] < 0)
                {
                    i++;
                }
                else
                {
                    j--;
                }
            }
            return count;
        }

        /// <summary>
        /// ThreeSum 的快速實現。(平方級別)
        /// </summary>
        /// <param name="a">需要查找的數組範圍。</param>
        /// <returns>數組中和為零的三元組數量。</returns>
        static int ThreeSumFaster(int[] a)
        {
            int count = 0;
            for (int i = 0; i < a.Length; ++i)
            {
                int lo = i + 1;
                int hi = a.Length - 1;
                while (lo <= hi)
                {
                    if (a[lo] + a[hi] + a[i] == 0)
                    {
                        count++;
                        lo++;
                        hi--;
                    }
                    else if (a[lo] + a[hi] + a[i] < 0)
                    {
                        lo++;
                    }
                    else
                    {
                        hi--;
                    }
                }
            }
            return count;
        }


1.4.16

題目

最接近一對(一維)。
編寫一個程式,給定一個含有 N 個 double 值的數組 a[],
在其中找到一對最接近的值:兩者之差(絕對值)最小的兩個數。
程式在最壞情況下所需的運行時間應該是線性對數級別的。

解答

先將數組從小到大排序,再遍歷一遍即可得到差距最小的兩個數。

排序演算法需要消耗 NlogN,具體見 MSDN:Array.Sort 方法 (Array)

代碼
using System;

namespace _1._4._16
{
    /*
     * 1.4.16
     * 
     * 最接近

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、Linux下目錄複製:本機->遠程伺服器 2、Linux下目錄複製:遠程伺服器->本機 3、Linux下文件複製:遠程伺服器->本機 -a 儘可能將檔案狀態、許可權等資料都照原狀予以複製。 -r 若 source 中含有目錄名,則將目錄下之檔案亦皆依序拷貝至目的地。 -f 若目的地已經有相同檔名的 ...
  • 繼上一篇文章: http://www.cnblogs.com/linhaostudy/p/7428971.html 四、file結構體 文件對象:註意文件對象描述的是進程已經打開的文件。因為一個文件可以被多個進程打開,所以一個文件可以存在多個文件對象。但是由於文件是唯一的,那麼inode就是唯一的, ...
  • Win10系統VMWare虛擬機無法連接網路的解決技巧: 第一步、打開VMWare虛擬機:依次點擊“編輯”,”虛擬網路編輯器”,“恢復預設設置” (期間要求賦予修改配置許可權、要求關閉已啟動的虛擬機),之後網路能用了。其實就是因為網路驅動有變化才導致不能用的,重裝下VMWare的網路模塊就好,正好恢復 ...
  • 學習Linux,就算是像小編我這樣的小萌新,也知道OSI模型。什麼?!你不知道!!! 好吧,這篇秘籍拿走,不謝~~~ 一、兩個協議 (1)OSI 協議模型(7層)國際協議 PDU:協議數據單元對等層次之間傳遞的數據單位 OSI協議(7層) 國際協議 PDU 單位 功能 實例 7 應用層 applic ...
  • Socket():創建套接字 Bind():綁定套接字。將一個本地協議地址賦予一個套接字 Listen():監聽套接字 Connect():建立與伺服器之間的連接。 accept():接收連接, Send():發送函數 recv():接收函數 close():關閉連接 伺服器端順序: Socket( ...
  • 版本: 主機:Windows 7 64位旗艦版 虛擬機: VMWare 12 + Windows 7 64位旗艦版 VMWare pro 12 + Ubuntu16.04LTS 64位 註:由於VMWare 10 跟 Ubuntu 16.04LTS版本不相容,會出現VMWare Tools 安裝過程 ...
  • 在 ASP.NET 中,我們知道,它有一個面向切麵的請求管道,有19個主要的事件構成,能夠讓我們進行靈活的擴展。通常是在 web.config 中通過註冊 HttpModule 來實現對請求管道事件監聽,並通過 HttpHandler 進入到我們的應用程式中。而在 ASP.NET Core 中,對請 ...
  • 有時候,我們運營的公眾號,可能因為某些原因而需要更換公眾號,比如,公司被收購,公眾號轉讓等。 那原有公眾號的粉絲,我們自然也想讓其遷移到新的公眾號上,一般做法是通過微信自帶的粉絲轉移功能。 但流程也不少,還要交300元的審核費用。最要命的是,如果你的公眾號平臺提供了一些系統,那麼用戶在系統上的資料是 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...