diff --git a/1 Fundamental/1.4/1.4.24/Program.cs b/1 Fundamental/1.4/1.4.24/Program.cs index a74ee282c..54384bccf 100644 --- a/1 Fundamental/1.4/1.4.24/Program.cs +++ b/1 Fundamental/1.4/1.4.24/Program.cs @@ -14,11 +14,11 @@ namespace _1._4._24 */ class Program { - static int F = 100;//需要寻找的 F 值 + static int F = 100;// 需要寻找的 F 值 struct testResult { - public int F; - public int BrokenEggs; + public int F;// 找到的 F 值。 + public int BrokenEggs;// 打碎的鸡蛋数。 } static void Main(string[] args) { @@ -27,12 +27,12 @@ static void Main(string[] args) { building[i] = i; } - //第一问:二分查找即可 + // 第一问:二分查找即可 testResult A = PlanA(building); Console.WriteLine($"Plan A: F={A.F}, Broken Eggs={A.BrokenEggs}"); - //第二问:按照第 1, 2, 4, 8,..., 2^k 层顺序查找,一直到 2^k > F, - //随后在 [2^(k - 1), 2^k] 范围中二分查找。 + // 第二问:按照第 1, 2, 4, 8,..., 2^k 层顺序查找,一直到 2^k > F, + // 随后在 [2^(k - 1), 2^k] 范围中二分查找。 testResult B = PlanB(building); Console.WriteLine($"Plan B: F={B.F}, Broken Eggs={B.BrokenEggs}"); } diff --git a/1 Fundamental/1.4/1.4.25/Program.cs b/1 Fundamental/1.4/1.4.25/Program.cs index cb03e464d..fa7059676 100644 --- a/1 Fundamental/1.4/1.4.25/Program.cs +++ b/1 Fundamental/1.4/1.4.25/Program.cs @@ -14,12 +14,12 @@ namespace _1._4._25 */ class Program { - static int F = 100;//需要寻找的 F 值 + static int F = 100;// 需要寻找的 F 值 struct testResult { - public int F; - public int BrokenEggs; - public int ThrowTimes; + public int F;// 测试得出的 F 值 + public int BrokenEggs;// 碎掉的鸡蛋数。 + public int ThrowTimes;// 扔鸡蛋的次数。 } static void Main(string[] args) { @@ -28,13 +28,13 @@ static void Main(string[] args) { building[i] = i; } - //第一问:第一个蛋按照 √(N), 2√(N), 3√(N), 4√(N),..., √(N) * √(N) 顺序查找直至碎掉。这里扔了 k 次,k <= √(N) - //k-1√(N) ~ k√(N) 顺序查找直至碎掉,F 值就找到了。这里最多扔 √(N) 次。 + // 第一问:第一个蛋按照 √(N), 2√(N), 3√(N), 4√(N),..., √(N) * √(N) 顺序查找直至碎掉。这里扔了 k 次,k <= √(N) + // k-1√(N) ~ k√(N) 顺序查找直至碎掉,F 值就找到了。这里最多扔 √(N) 次。 testResult A = PlanA(building); Console.WriteLine($"Plan A: F={A.F}, Broken Eggs={A.BrokenEggs}, Throw Times={A.ThrowTimes}"); - //第二问:按照第 1, 3, 6, 10,..., 1/2k^2 层顺序查找,一直到 1/2k^2 > F, - //随后在 [1/2k^2 - k, 1/2k^2] 范围中顺序查找。 + // 第二问:按照第 1, 3, 6, 10,..., 1/2k^2 层顺序查找,一直到 1/2k^2 > F, + // 随后在 [1/2k^2 - k, 1/2k^2] 范围中顺序查找。 testResult B = PlanB(building); Console.WriteLine($"Plan B: F={B.F}, Broken Eggs={B.BrokenEggs}, Throw Times={B.ThrowTimes}"); } diff --git a/1 Fundamental/1.4/1.4.26/Program.cs b/1 Fundamental/1.4/1.4.26/Program.cs index bd5ac5669..29c3f0394 100644 --- a/1 Fundamental/1.4/1.4.26/Program.cs +++ b/1 Fundamental/1.4/1.4.26/Program.cs @@ -12,20 +12,20 @@ class Program { static void Main(string[] args) { - //证明点 A(a, a^3) B(b, b^3) C(c, c^3) 当且仅当 a + b + c = 0 时共线。 + // 证明点 A(a, a^3) B(b, b^3) C(c, c^3) 当且仅当 a + b + c = 0 时共线。 // - //若点 A,B,C 共线,直线 AB 斜率必定和直线 BC 斜率相等,列方程有: - //(b^3 - a^3)/(b - a) = (c^3 - b^3)/(c - b) - //用立方差公式化简,有: - //b^2 + ab + a^2 = c^2 + bc + b^2 - //消去 b^2,将 c 设为未知数有 - //c^2 +bc - a^2 - ab = 0 - //用十字相乘法进行因式分解有 - //(a + b + c)(c - a) = 0 - //解方程有: - //c = -a - b 或 c = a - //因此当 c != a 时,当且仅当 a + b + c = 0 时 A, B, C 三点共线。 - //得证。 + // 若点 A,B,C 共线,直线 AB 斜率必定和直线 BC 斜率相等,列方程有: + // (b^3 - a^3)/(b - a) = (c^3 - b^3)/(c - b) + // 用立方差公式化简,有: + // b^2 + ab + a^2 = c^2 + bc + b^2 + // 消去 b^2,将 c 设为未知数有 + // c^2 +bc - a^2 - ab = 0 + // 用十字相乘法进行因式分解有 + // (a + b + c)(c - a) = 0 + // 解方程有: + // c = -a - b 或 c = a + // 因此当 c != a 时,当且仅当 a + b + c = 0 时 A, B, C 三点共线。 + // 得证。 } } } diff --git a/1 Fundamental/1.4/1.4.27/StackQueue.cs b/1 Fundamental/1.4/1.4.27/StackQueue.cs index fe3786712..c6bf78f7b 100644 --- a/1 Fundamental/1.4/1.4.27/StackQueue.cs +++ b/1 Fundamental/1.4/1.4.27/StackQueue.cs @@ -6,8 +6,8 @@ /// 队列中的元素。 class StackQueue { - Stack H;//用于保存出队元素 - Stack T;//用于保存入队元素 + Stack H;// 用于保存出队元素 + Stack T;// 用于保存入队元素 /// /// 构造一个队列。 @@ -35,7 +35,7 @@ private void Reverse() /// public Item Dequeue() { - //如果没有足够的出队元素,则将 T 中的元素移动过来 + // 如果没有足够的出队元素,则将 T 中的元素移动过来 if (this.H.IsEmpty()) { Reverse(); diff --git a/1 Fundamental/1.4/1.4.28/QueueStack.cs b/1 Fundamental/1.4/1.4.28/QueueStack.cs index af8f93c06..f6157b34f 100644 --- a/1 Fundamental/1.4/1.4.28/QueueStack.cs +++ b/1 Fundamental/1.4/1.4.28/QueueStack.cs @@ -24,7 +24,7 @@ public void Push(Item item) { this.queue.Enqueue(item); int size = this.queue.Size(); - //倒转队列 + // 倒转队列 for (int i = 0; i < size - 1; ++i) { this.queue.Enqueue(this.queue.Dequeue()); diff --git a/1 Fundamental/1.4/1.4.29/StackSteque.cs b/1 Fundamental/1.4/1.4.29/StackSteque.cs index 4cf3ab19d..ec4ff279c 100644 --- a/1 Fundamental/1.4/1.4.29/StackSteque.cs +++ b/1 Fundamental/1.4/1.4.29/StackSteque.cs @@ -24,13 +24,14 @@ public StackSteque() /// public void Push(Item item) { + ReverseT(); this.H.Push(item); } /// /// 将 T 中的元素弹出并压入到 H 中。 /// - private void Reverse() + private void ReverseT() { while (!this.T.IsEmpty()) { @@ -39,16 +40,23 @@ private void Reverse() } /// - /// 从 Steque 中弹出一个元素。 + /// 将 H 中的元素弹出并压入到 T 中。 /// - /// - public Item Pop() + private void ReverseH() { - if (this.H.IsEmpty()) + while (!this.H.IsEmpty()) { - Reverse(); + this.T.Push(this.H.Pop()); } + } + /// + /// 从 Steque 中弹出一个元素。 + /// + /// + public Item Pop() + { + ReverseT(); return this.H.Pop(); } @@ -58,6 +66,7 @@ public Item Pop() /// public void Enqueue(Item item) { + ReverseH(); this.T.Push(item); } diff --git a/1 Fundamental/1.4/1.4.30/Deque.cs b/1 Fundamental/1.4/1.4.30/Deque.cs index d0061e40d..1755a0471 100644 --- a/1 Fundamental/1.4/1.4.30/Deque.cs +++ b/1 Fundamental/1.4/1.4.30/Deque.cs @@ -6,8 +6,8 @@ /// 双向队列中保存的元素类型。 class Deque { - Stack stack;//代表队列尾部 - Steque steque;//代表队列头部 + Stack stack;// 代表队列尾部 + Steque steque;// 代表队列头部 /// /// 创建一条空的双向队列。 @@ -68,7 +68,14 @@ public Item PopLeft() /// 要插入的元素。 public void PushRight(Item item) { - this.stack.Push(item); + if (this.stack.IsEmpty()) + { + this.steque.Enqueue(item); + } + else + { + this.stack.Push(item); + } } /// diff --git a/1 Fundamental/1.4/1.4.31/Deque.cs b/1 Fundamental/1.4/1.4.31/Deque.cs index 82149e618..255c7d110 100644 --- a/1 Fundamental/1.4/1.4.31/Deque.cs +++ b/1 Fundamental/1.4/1.4.31/Deque.cs @@ -46,17 +46,17 @@ public void PushRight(Item item) private void Move(Stack source, Stack destination) { int n = source.Size(); - //将上半部分元素移动到临时栈 middle + // 将上半部分元素移动到临时栈 middle for (int i = 0; i < n / 2; ++i) { this.middle.Push(source.Pop()); } - //将下半部分移动到另一侧栈中 + // 将下半部分移动到另一侧栈中 while (!source.IsEmpty()) { destination.Push(source.Pop()); } - //从 middle 取回上半部分元素 + // 从 middle 取回上半部分元素 while (!this.middle.IsEmpty()) { source.Push(this.middle.Pop()); diff --git a/1 Fundamental/1.4/1.4.32/Program.cs b/1 Fundamental/1.4/1.4.32/Program.cs index f87d06b98..bb985a4a0 100644 --- a/1 Fundamental/1.4/1.4.32/Program.cs +++ b/1 Fundamental/1.4/1.4.32/Program.cs @@ -16,7 +16,7 @@ static void Main(string[] args) // 这里简单证明,设 M 次操作之后栈的大小为 n,那么额外访问数组的次数为: // S = n/2 + n/4 + n/8 +...+ 2 < n // 为了能使栈大小达到 n,M 必须大于等于 n/2 - // 因此 2M >= n > S,得证。 + // 因此 2M >= n > S,得证。 // 因此我们可以得到 M 次操作后访问数组次数的总和 S' = S + M < 3M // 得证。 } diff --git a/1 Fundamental/1.4/1.4.33/Program.cs b/1 Fundamental/1.4/1.4.33/Program.cs index 89375cff1..9b3d0cd6c 100644 --- a/1 Fundamental/1.4/1.4.33/Program.cs +++ b/1 Fundamental/1.4/1.4.33/Program.cs @@ -18,7 +18,7 @@ static void Main(string[] args) // int[] = 8(对象开销) + 4(数组长度) + 4N = 12 + 4N // double[] = 8(对象开销) + 4(数组长度) + 8N = 12 + 8N // double[][] = 8(对象开销) + 4(数组长度) + 4M(引用) + M(12 + 8N)(M 个一维数组) = 12 + 16M + 8MN - // String = 8(对象开销) + 3*4(int * 3) + 4(字符数组的引用) + 8(字符数组对象开销) + 4(字符数组长度) + 2N(字符串) = 36 + 2N + // String = 8(对象开销) + 3*4(int * 3) + 4(字符数组的引用) = 24 // Node = 8(对象开销) + 4*2(引用*2) = 16 // Stack = 8(对象开销) + 4(引用) + 4(int) + N(Node + Integer)(元素) = 16 + 28N } diff --git a/1 Fundamental/1.4/1.4.34/Program.cs b/1 Fundamental/1.4/1.4.34/Program.cs index b7e4f8eed..6f1f587a2 100644 --- a/1 Fundamental/1.4/1.4.34/Program.cs +++ b/1 Fundamental/1.4/1.4.34/Program.cs @@ -19,8 +19,8 @@ class Program /// struct TestResult { - public int SecretNumber; - public int TryTimes; + public int SecretNumber;// 猜测到的数字。 + public int TryTimes;// 尝试次数。 } static void Main(string[] args) @@ -87,7 +87,7 @@ static TestResult PlayGameA(Game game) } /// - /// 方案二,根据 (lastGuess + nowGuess) = (lo + hi) / 2 确定每次猜测的值。 + /// 方案二,根据 (lastGuess + nowGuess)/2 = (lo + hi) / 2 确定每次猜测的值。 /// /// 用于猜测的游戏对象。 /// 返回测试结果,包含猜测结果和尝试次数。 @@ -133,7 +133,6 @@ static TestResult PlayGameB(Game game) { hi = mid; } - } else { diff --git a/1 Fundamental/1.4/1.4.35/Program.cs b/1 Fundamental/1.4/1.4.35/Program.cs index e2597d0c7..acf3ff6cd 100644 --- a/1 Fundamental/1.4/1.4.35/Program.cs +++ b/1 Fundamental/1.4/1.4.35/Program.cs @@ -20,7 +20,7 @@ class Program { static void Main(string[] args) { - // 1. 一个 Node 对象包含一个 int(泛型 Item) 的引用和下一个 Node 对象的引用。 + // 1. 一个 Node 对象包含一个 int(泛型 Item) 的引用和下一个 Node 对象的引用。push 操作创建 Node 对象时会创建一个引用。 // 因此对于第一种情况,压入 n 个 int 类型的元素创建了 N 个 Node 对象,创建了 2N 个引用。 // 2. 比起上一种情况,每个 Node 对象多包含了一个指向 Integer 的引用。 // 因此对于第二中情况,压入 n 个 int 类型的元素创建了 N 个 Node 对象和 N 个 Integer 对象,比起第一种情况多创建了 N 个引用。 diff --git a/1 Fundamental/1.4/1.4.41/DoublingRatio.cs b/1 Fundamental/1.4/1.4.41/DoublingRatio.cs index 2b1251fd0..2cd4fae5a 100644 --- a/1 Fundamental/1.4/1.4.41/DoublingRatio.cs +++ b/1 Fundamental/1.4/1.4.41/DoublingRatio.cs @@ -39,7 +39,7 @@ public static double TimeTrial(Count Count, int[] a) /// /// 对 TwoSum、TwoSumFast、ThreeSum 或 ThreeSumFast 的 Count 方法做测试。 /// - /// 相应类的 Count 方法 + /// 相应类的 Count 方法。 /// 随着数据量倍增,方法耗时增加的比率。 public static double Test(Count Count) { @@ -97,6 +97,11 @@ public static double Test(Count Count) return ratio / times; } + /// + /// 对 TwoSumFast 的 Count 方法做测试。 + /// + /// TwoSumFast 的 Count 方法 + /// 随着数据量倍增,方法耗时增加的比率。 public static double TestTwoSumFast(Count Count) { double ratio = 0;