1.2.9 #
解答 #
首先实现一个 Counter 类,随后使用非递归版本的 BinarySearch,每进行一次 While 循环就让 Counter 加一。
代码 #
Counter 类 #
class Counter
{
private readonly string _name;
private int _count;
/// <summary>
/// 构造函数。
/// </summary>
/// <param name="id">计数器的名称。</param>
public Counter(string id)
{
_name = id;
}
/// <summary>
/// 计数器加一。
/// </summary>
public void Increment()
{
_count++;
}
/// <summary>
/// 获取当前计数值。
/// </summary>
/// <returns></returns>
public int Tally()
{
return _count;
}
/// <summary>
/// 输出形如 “1 counter” 的字符串。
/// </summary>
/// <returns></returns>
public override string ToString()
{
return _count + " " + _name;
}
}
Main #
// 参考 1.1.10 节的代码
var count = new Counter("BinarySearch");
// 读取白名单
var whiteListString = File.ReadAllLines("tinyW.txt");
var whiteList = new int[whiteListString.Length];
for (var i = 0; i < whiteListString.Length; i++)
{
whiteList[i] = int.Parse(whiteListString[i]);
}
Array.Sort(whiteList);
// 读取查询值
var inputListString = File.ReadAllLines("tinyT.txt");
var inputList = new int[inputListString.Length];
for (var i = 0; i < inputListString.Length; i++)
{
inputList[i] = int.Parse(inputListString[i]);
}
// 对每一个查询值进行二分查找
foreach (var n in inputList)
{
var result = Rank(n, whiteList, count);
// 将不在白名单上的数据输出
if (result == -1)
{
Console.WriteLine(n);
}
}
Console.WriteLine();
// 输出查询数目
Console.WriteLine(count.Tally());
static int Rank(int key, int[] a, Counter count)
{
var lo = 0;
var hi = a.Length - 1;
while (lo <= hi)
{
var mid = lo + (hi - lo) / 2;
count.Increment();
if (key < a[mid])
{
hi = mid - 1;
}
else if (key > a[mid])
{
lo = mid + 1;
}
else
{
return mid;
}
}
return -1;
}