Fundamental

1.2.12

2018-5-16
Fundamental

1.2.12 # 解答 # 这里使用蔡勒公式来推算星期。 参考:http://www.cnblogs.com/mq0036/p/3534314.html 代码 # /// <summary> /// 计算当前日期是星期几,返回对应的星期名称。 /// </summary> /// <returns></returns> public string DayOfTheWeek() { var d = Day; var m = Month; var y = Year; if (m < 3) { m += 12; y--; } // 使用蔡勒公式计算,参见 http://www.cnblogs.com/mq0036/p/3534314.html var w = (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7; return DayOfWeek[w]; } 另请参阅 # 蔡勒公式-维基百科

1.2.13

2018-5-16
Fundamental

1.2.13 # 解答 # 直接实现即可。 JAVA 版本可以参考:http://algs4.cs.princeton.edu/12oop/Transaction.java.html。 代码 # public class Transaction : IComparable<Transaction> { /// <summary> /// 客户姓名。 /// </summary> /// <value>客户姓名。</value> public string Who { get; } /// <summary> /// 交易日期。 /// </summary> /// <value>交易日期。</value> /// <seealso cref="Date"/> public Date When { get; } /// <summary> /// 交易金额。 /// </summary> /// <value>交易金额。</value> public double Amount { get; } /// <summary> /// 构造函数。 /// </summary> /// <param name="transaction">用空格隔开的形如 “姓名 日期 金额” 的字符串。</param> public Transaction(string transaction) { var a = transaction. ...

1.2.14

2018-5-16
Fundamental

1.2.14 # 解答 # 上一题中的代码已经包含了对 Equals() 方法的实现。 代码 # /// <summary> /// 比较两笔交易是否相同。 /// </summary> /// <param name="obj">另一个对象。</param> /// <returns></returns> public override bool Equals(object obj) { if (obj == this) return true; if (obj == null) return false; if (obj.GetType() != GetType()) return false; var that = (Transaction)obj; return Math.Abs(that.Amount - Amount) < float.Epsilon * 5 && that.When.Equals(When) && that.Who == Who; } 另请参阅 # Commercial 库

1.2.15

2018-5-16
Fundamental

1.2.15 # 解答 # 这里我们基于 File.ReadAllLines() 进行实现。 代码 # static int[] ReadInts(string path) { var allLines = File.ReadAllLines(path); var result = new int[allLines.Length]; for (var i = 0; i < allLines.Length; i++) { result[i] = int.Parse(allLines[i]); } return result; }

1.2.16

2018-5-16
Fundamental

1.2.16 # 解答 # JAVA 版本参考:http://algs4.cs.princeton.edu/12oop/Rational.java.html 欧几里得算法仅适用于正整数,使用前需要注意。 用欧几里得算法找到公因子之后直接化简即可。 代码 # public class Rational { public long Numerator { get; } public long Denominator { get; } private readonly bool _isNegative; /// <summary> /// 构造一个有理数对象,自动变为最简形式。 /// </summary> /// <param name="numerator">分子。</param> /// <param name="denominator">分母。</param> /// <exception cref="ArgumentException">分母为 0 时抛出</exception> public Rational(long numerator, long denominator) { if (denominator == 0) throw new ArgumentException("Denominator cannot be 0"); if (numerator < 0 && denominator < 0) { _isNegative = false; numerator = -numerator; denominator = -denominator; } else if (numerator < 0 || denominator < 0) { _isNegative = true; } else { _isNegative = false; } var gcd = Gcd(Math. ...

1.2.17

2018-5-16
Fundamental

1.2.17 # 解答 # 在 C# 中使用 checked 关键字包裹整数运算的代码即可自动检查溢出。 在 JAVA 中可以考虑在运算前控制运算数的大小。 例如 a + b 之前保证 long.MaxValue – b >= a 等等。 代码 # public class Rational { public long Numerator { get; } public long Denominator { get; } private readonly bool _isNagative; /// <summary> /// 构造一个有理数对象,自动变为最简形式。 /// </summary> /// <param name="numerator">分子。</param> /// <param name="denominator">分母。</param> /// <exception cref="ArgumentException">分母为 0 时抛出</exception> public Rational(long numerator, long denominator) { if (denominator == 0) throw new ArgumentException("Denominator cannot be 0"); if (numerator < 0 && denominator < 0) { _isNagative = false; numerator = -numerator; denominator = -denominator; } else if (numerator < 0 || denominator < 0) { _isNagative = true; } else { _isNagative = false; } var gcd = Gcd(Math. ...

1.2.18

2018-5-16
Fundamental

1.2.18 # 解答 # 当数据比较大时—— 例如 10^9 加上随机小数组成的数列,这时 double 的小数精度将受限。 求和之后整数部分更大,小数部分将自动四舍五入,出现误差 这时再计算平均值时将会带来较大的误差。 因此采用另一个递推公式: k 为下标。 $M_k = M_{k-1}+ (x_k – M_{k-1})/k$ $S_k = S_{k-1} + (x_k – M_{k-1})\times(x_k – M_k)$. 方差 $s^2 = S_k/(k – 1)$. 这种情况下并没有直接对所有输入值求和,小数精度不会过多受到整数部分长度的影响。 有关这两个公式的证明可以参考这篇论文,或者去查看我的知乎回答。 代码 # public class Accumulator { private double _m; private double _s; private int _n; public void AddDataValue(double x) { _n++; _s = _s + 1.0 * (_n - 1) / _n * (x - _m) * (x - _m); _m = _m + (x - _m) / _n; } public double Mean() { return _m; } public double Var() { return _s / (_n - 1); } public double Stddev() { return Math. ...

1.2.19

2018-5-16
Fundamental

1.2.19 # 解答 # 之前的 Date 和 Transaction 已经包含了这些实现。 代码 # Date # /// <summary> /// 构造函数。 /// </summary> /// <param name="date">形如 "05/31/2017" 的字符串。</param> public Date(string date) { string[] a = date.Split('/'); if (a.Length != 3) throw new ArgumentException("Illgal Date"); Month = int.Parse(a[0]); Day = int.Parse(a[1]); Year = int.Parse(a[2]); } Transaction # /// <summary> /// 构造函数。 /// </summary> /// <param name="transaction">用空格隔开的形如 “姓名 日期 金额” 的字符串。</param> public Transaction(string transaction) { string[] a = transaction. ...

1.3.1

2018-5-16
Fundamental

1.3.1 # 解答 # 首先是 FixedCapacityStackOfStrings 类,官方 JAVA 版本参考:FixedCapacityStackOfStrings.java IsFull() 的实现比较简单,判断 N 与数组长度是否相等即可。 代码 # internal class FixedCapacityStackOfStrings : IEnumerable<string> { private readonly string[] _a; private int _n; /// <summary> /// 默认构造函数。 /// </summary> /// <param name="capacity">栈的大小。</param> public FixedCapacityStackOfStrings(int capacity) { _a = new string[capacity]; _n = 0; } /// <summary> /// 检查栈是否为空。 /// </summary> /// <returns></returns> public bool IsEmpty() { return _n == 0; } /// <summary> /// 检查栈是否已满。 /// </summary> /// <returns></returns> public bool IsFull() { return _n == _a. ...

1.3.2

2018-5-16
Fundamental

1.3.2 # 解答 # 首先是 Stack<> 类的实现,官方 JAVA 版本参考:Stack.java 输出内容:was best times of the was the it 代码 # /// <summary> /// 栈类(链表实现)。 /// </summary> /// <typeparam name="TItem">栈中存放的元素类型。</typeparam> public class Stack<TItem> : IEnumerable<TItem> { private Node<TItem> _first; private int _count; /// <summary> /// 默认构造函数。 /// </summary> public Stack() { _first = null; _count = 0; } /// <summary> /// 复制构造函数,链表中的元素都是浅拷贝。 /// </summary> /// <param name="s">用于复制的栈。</param> public Stack(Stack<TItem> s) { if (s. ...