【问题标题】:string/integer associations in CC中的字符串/整数关联
【发布时间】:2014-07-26 08:43:26
【问题描述】:

对于以下问题,我想用 c 语言提出建议:

我需要这样的字符串和整数之间的关联:

"foo" => 45,
"bar" => 1023,
 etc...

并且能够使用相关的整数和使用相关字符串的整数来查找字符串。 对于字符串到整数,我可以使用哈希表,但我会放宽回去的路。

我正在使用但速度很慢的简单解决方案是创建一个表: 静态 param_t 参数 [] = { { "foo", 45 }, { "酒吧", 1023 }, ... }; 并使用两个函数比较每个条目(字符串或整数)以获取字符串或整数。 这是非常慢的线性搜索。 我可以使用什么来在 O(1) 中使用搜索算法来查找字符串并在 O(字符串大小) 中查找整数? 有什么想法吗?

【问题讨论】:

标签: c string hash integer associations


【解决方案1】:

最简单的方法是实现查找表,最好按整数值(“主键”)排序。

typedef enum
{
  FOO_INDEX,
  BAR_INDEX,
  ...  
  N
} some_t;

const int int_array [] =  // values sorted in ascending order, smallest first
{
  45,
  1023,
  ...
};

const char* str_array [] =
{
  "foo",
  "bar",
  ...
};

现在您可以使用int_array[FOO_INDEX]str_array[FOO_INDEX] 来获取所需的数据。

由于这些是在编译时设置的常量表,您可以对数据进行排序。然后可以使用二分查找 O(log n) 来完成所有查找。如果您有整数值但需要知道索引,请对 int_array 执行二进制搜索。一旦找到索引,您就可以从那里立即查找。

为此,两个数组必须具有精确的大小N。要确保这些数组中的数组大小和数据完整性,请使用编译时断言:

static_assert(sizeof(int_array)/sizeof(*int_array) == N, "Bad int_array");
static_assert(sizeof(str_array)/sizeof(*str_array) == N, "Bad str_array");

【讨论】:

  • 很好的答案,但值得注意的是,如果您使用 static_assertion,则必须在没有 N 的情况下声明数组(如 const int int_array [] = { ... })。否则断言不会检测到太短的初始化列表。
  • @user694733 哦,当然,我不确定我在想什么。我会编辑,谢谢。
  • 不是static_assertC++吗?
  • 好的,但是我如何获得具有整数 1023 的字符串“bar”?我仍然需要找到它的位置。
  • @user3710871 "如果您有整数值但需要知道索引,请对 int_array 执行二进制搜索。"所以当搜索 1024 时,你会得到索引 1(等于 BAR_INDEX)。然后直接访问str_array[1]就可以得到对应的字符串。
【解决方案2】:

首先使用qsort 对您的列表进行排序,然后使用bsearch 查找项目。不是 O(1),但至少是 O(log(n))。

【讨论】:

    【解决方案3】:

    使用两个哈希图。一种是整数到字符串的关联,另一种是字符串到整数的关联。

    【讨论】:

    • 只有当你有字符串并且需要获取整数时才真正需要哈希映射,即当字符串是主键时。即使那样,您也可能只使用一个普通的排序表。虽然如果允许重复,哈希映射很有用。
    • 如果我已经有一个 Hashmap 实现(就像我会使用 perl 或 Java),我会同时使用它。只有当我必须自己实现一个时,我才会考虑使用其他东西来进行从整数到字符串的关联。
    【解决方案4】:

    一种低效的方法是将其转换为基数 256。第一个字母 ASCII 乘以 256 的 0 (1) 次方加上第二个字​​母 ASCII 乘以 256 的 1 次方,依此类推。非常低效(因为 long 不够,所以要么在另一个字符串中包含数字,要么使用数学 C 库。我知道 Ruby 和 Perl 中有散列,它基本上是一个数组,你可以使用某个键进入(可以是一个字符串),但我不知道它是如何工作的。

    【讨论】:

      猜你喜欢
      • 2018-05-29
      • 1970-01-01
      • 2016-07-08
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 1970-01-01
      相关资源
      最近更新 更多