C#,初学琼林(04)——查询(搜索)数组内指定(值)的元素与全文检索“倒排序”技术的实现代码源程序
假设我们有一个 n 元素数组,我们想在其中找到给定元素 x 的元素。a 是一个索引从 0 到 n-1 的数组 。它的元素将被标记为:a[0], a[1],a[2],a[3],...,a[n-1]。
要找到 x 元素,我们将采取以下步骤:
- 我们将遍历数组的下一个元素,如果数组的给定元素等于 x,我们已经找到了搜索的元素并完成搜索,
- 如果我们已经到达数组的末尾,则意味着给定的元素 X 不在我们的数组中。
1、原始算法
最原始的算法,仅仅是实现相应的逻辑。
private void button1_Click(object sender, EventArgs e)
{
int[] a = { 10, -5, 2, 3, 88, 6, -19, 23 };
int x = 3;
for (int i = 0; i < a.Length; i++)
{
if (a[i] == x)
{
MessageBox.Show("在数组a的第" + (i + 1) + "个位置找到" + x, "搜索数组指定元素");
return;
}
}
MessageBox.Show("未能在数组a中找到" + x, "搜索数组指定元素");
}
2、转为列表算法
如果只是为了确定是否存在相应的数值,则转为列表 List<int> 可以简约代码。
using System.Linq;
private void button1_Click(object sender, EventArgs e)
{
int[] a = { 10, -5, 2, 3, 88, 6, -19, 23 };
int x = 3;
List<int> list = a.ToList();
if (list.Exists(t => t == x))
{
MessageBox.Show("在数组中找到" + x, "搜索数组指定元素");
return;
}
MessageBox.Show("未能在数组a中找到" + x, "搜索数组指定元素");
}
3、高效的哈希表算法
实际应用中的需求往往至少是:
(1)数组的单元数很多,也就是 a.Length 很大;
(2)多次搜索数值单元;
(3)需要知道数值单元的位置(索引);
前面的两个算法就很 low,只能出现于教材与教室。
工业化、商品化的软件会大致按下面的思路编写:
Part of Form1.cs
private void button1_Click(object sender, EventArgs e)
{
int[] a = { 10, -5, 2, 3, 88, 3, -19, 23 };
int x = 3;
string n = HArray.Found(a, x);
if (n.Length > 0)
{
MessageBox.Show("在数组中的索引" + n + "找到" + x, "搜索数组指定元素");
return;
}
MessageBox.Show("未能在数组a中找到" + x, "搜索数组指定元素");
}
HArray.cs
public static class HArray
{
/// <summary>
/// 保存数值及其对应索引(列表)的哈希表
/// </summary>
private static Hashtable hash = new Hashtable();
/// <summary>
/// 默认的索引数据分割字符
/// </summary>
private static string spliter { get; } = ",";
/// <summary>
/// 哈希表初始化
/// </summary>
/// <param name="a"></param>
private static void Initialize(int[] a)
{
for (int i = 0; i < a.Length; i++)
{
if (!hash.ContainsKey(a[i])) hash.Add(a[i], i + "");
else
{
string n = (string)hash[a[i]];
hash[a[i]] = n + spliter + i;
}
}
}
/// <summary>
/// 搜索x对应的位置(列表)
/// </summary>
/// <param name="a">数值</param>
/// <param name="x">搜索的数值</param>
/// <returns>返回索引(列表)的字符串</returns>
public static string Found(int[] a, int x)
{
if (hash.Count == 0) Initialize(a);
if (hash.ContainsKey(x)) return (string)hash[x];
return "";
}
/// <summary>
/// 将逗号分割的索引(字符串)转为数组
/// </summary>
/// <param name="s"></param>
/// <returns>索引数组</returns>
public static int[] ToIndex(string s)
{
string[] sa = s.Split(new char[] { spliter[0] }, StringSplitOptions.RemoveEmptyEntries);
int[] r = new int[sa.Length];
int i = 0;
foreach (string sx in sa)
{
r[i++] = Int32.Parse(sx);
}
return r;
}
}
POWER BY 315SOFT.COM
实际上,上述代码稍微修改(int --> string or char)就是 全文检索 中常见的 倒排序 索引技术的具体实现源程序了。