Fundamental

1.1.11

2018-5-14
Fundamental

1.1.11 # 解答 # 注意,二维数组 bool[M, N] 代表 M 行 N 列的布尔数组。 使用二重循环即可实现。 输出使用制表符 ’\t’ 作为分隔。 代码 # var array = new[,] { { true, true }, { false, false }, { true, false } }; PrintArray2D(array); // 打印二维数组 static void PrintArray2D(bool[,] array) { var rows = array.GetLength(0); // 获取行数 var columns = array.GetLength(1); // 获取列数 //输出列号 for (var i = 0; i < columns; i++) { Console.Write($"\t{i + 1}"); } Console. ...

1.1.12

2018-5-14
Fundamental

1.1.12 # 解答 # 第一个循环初始化数组 {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} 第二个循环用相应位置的值作为下标取值,例如:a[0] = a[a[0]] = a[9] = 0 最后结果为:0,1,2,3,4,4,3,2,1,0 代码 # var a = new int[10]; for (var i = 0; i < 10; i++) { a[i] = 9 - i; } // a[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0} for (var i = 0; i < 10; i++) { a[i] = a[a[i]]; } // a[0] = a[9] = 0; a[1] = a[8] = 1; a[2] = a[7] = 2;. ...

1.1.13

2018-5-14
Fundamental

1.1.13 # 解答 # 转置输出只需要在二重循环的时候将行、列输出顺序取反即可。 代码 # var m = 2; var n = 3; var array = new int[m, n]; // 新建一个二维数组 for (var i = 0; i < m; i++) { for (var j = 0; j < n; j++) { array[i, j] = i + j; } } Console.WriteLine("Origin"); PrintArray2D(array, m, n); Console.WriteLine("Transposed"); PrintArrayTranspose2D(array, m, n); // 转置输出 static void PrintArrayTranspose2D(int[,] array, int rows, int columns) { // 交换行、列输出顺序 for (var i = 0; i < columns; i++) { for (var j = 0; j < rows; j++) { Console. ...

1.1.14

2018-5-14
Fundamental

1.1.14 # 解答 # 简单使用 log 的定义逼近即可。 代码 # const int n = 9; Console.WriteLine($"{Lg(n)}"); // 利用循环逼近 n,得到 log2(n) 的值 static int Lg(int n) { const int baseNumber = 2; var pow = 1; var sum = 2; for (pow = 1; sum < n; pow++) { sum *= baseNumber; } return pow - 1; }

1.1.15

2018-5-14
Fundamental

1.1.15 # 解答 # 利用二重循环,查找每个值在数组中出现的次数。 代码 # var a = new int[10]; const int m = 10; for (var i = 0; i < 10; i++) { a[i] = i; } var result = Histogram(a, m); Console.WriteLine($"a.length: {a.Length}"); Console.WriteLine($"sum of result array: {result.Sum()}"); static int[] Histogram(int[] a, int m) { var result = new int[m]; for (var i = 0; i < m; i++) { // 初始化 result[i] = 0; // 遍历数组,计算数组中值为 i 的元素个数 for (var j = 0; j < a. ...

1.1.16

2018-5-14
Fundamental

1.1.16 # 解答 # 填入代码测试即可。 用字符串拼接的方式展示递归。 代码 # Console.WriteLine($"{ExR1(6)}"); // ExR1(6) = // ExR1(3) + 6 + ExR1(4) + 6 // ExR1(0) + 3 + ExR1(1) + 3 + 6 + ExR1(4) + 6 // "" + 3 + ExR1(-2) + 1 + ExR1(-1) + 1 + 3 + 6 + ExR1(4) + 6 // "" + 3 + "" + 1 + "" + 1 + 3 + 6 + ExR1(4) + 6 // "31136" + ExR1(4) + 6 // . ...

1.1.17

2018-5-14
Fundamental

1.1.17 # 解答 # 书中已经给出了解释。 递归时结束条件必须放在递归语句的前面,否则会不断展开而无法结束。 代码 # Console.WriteLine($"{ExR2(6)}"); // 抛出 StackOverflow Exception static string ExR2(int n) { var s = ExR2(n - 3) + n + ExR2(n - 2) + n; // 运行到 ExR2 即展开,不会再运行下一句 if (n <= 0) { return ""; } return s; }

1.1.18

2018-5-14
Fundamental

1.1.18 # 解答 # 其实就是一种快速乘法的实现,换成乘号之后就变成了快速乘幂。 例如对于乘法 $2 \times 4$ ,可以用 $2 + 2 + 2 + 2$ 做四次加法计算;也可以变为 $(2 + 2) \times 2 = (2 + 2) + (2 + 2)$ 的形式,用两次加法就可以完成(先计算 $2 + 2$ 的值,再计算 $4 + 4$ 的值)。 同理对于乘幂 $2^8$ ,既可以用 $2\times 2 \times 2 \times 2 \times 2 \times 2 \times 2 \times 2$ 做 8 次乘法,也可以只用三次乘法就计算出来: $$ 2^2 = 2 \times 2 \newline 2^4 = 2^2 \times 2^2\newline 2^8 = 2^4 \times 2^4 $$ ...

1.1.19

2018-5-14
Fundamental

1.1.19 # 解答 # 普通的递归算法效率很低,原因是越到后面重复运算的数目越多。 比如: F(2) = F(1) + F(0) F(3) = F(2) + F(1) = F(1) + F(1) + F(0) 可以看到 F(1) 被重复计算了两次。 改进的方式是将每次运算的结果保存在数组中,之后计算过的数据直接从数组中提取。 代码 # // long 类型不够大,换成 UINT64 类型 // 用于保存计算结果的数组,UInt64? 代表可以赋值为普通 UInt64 类型的值以及 null 值 var fibnacciResults = new UInt64?[100]; var timer = Stopwatch.StartNew(); for (var n = 0; n < 100; n++) { // 书本中的代码,非常慢,1小时后 n = 50 // Console.WriteLine($"{n} {F(n)}"); // 利用已知结果加速 // 全部计算完毕耗时 84ms Console. ...

1.1.20

2018-5-15
Fundamental

1.1.20 # 解答 # 根据对数的性质可以得到: $$ \ln(N!) = \ln(N) + \ln(N – 1) + \ln(N – 2)… $$ 代码 # const int n = 4; Console.WriteLine($"{FactorialLn(n)}"); // ln(N!) = // ln(N * (N - 1) * ... * 1) = // ln(N) + ln((N - 1)!) static double FactorialLn(int n) { if (n == 1) { return 0; } return Math.Log(n) + FactorialLn(n - 1); }