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)就是 全文检索 中常见的 倒排序 索引技术的具体实现源程序了。

猜你喜欢

转载自blog.csdn.net/beijinghorn/article/details/129903833