【问题标题】:C data structure for looking up 6-byte structure using ascii values passed使用传递的 ascii 值查找 6 字节结构的 C 数据结构
【发布时间】:2013-05-12 15:00:45
【问题描述】:

我需要一个用于 C 中的嵌入式系统的紧凑数据结构。给定一个表示 ascii 代码的字节,函数将返回该字体字符的 6 字节位图。只有少数字符的位图会在 ROM 中 - 例如,0-9、'.'、':' 和其他一些字符。

一种低效的解决方案是使用一个长度等于最高 Ascii 值的数组,该数组指向存储字符位图的第二个数组中的索引。例如,第一个数组将有 128 个一个字节的元素,如果我定义了 20 个字符的位图,第二个数组将有 20 个 6 个字节的元素。第一个数组中的元素值将映射到第二个数组中的索引,因此 ascii 值选择第一个数组中的元素,并且该元素的值用作第二个数组中的索引值以获取 6 字节位图。但这浪费了大约 100 个字节(在第一个数组中)。

有没有更好的方法? 谢谢

编辑:我想我将不得不使用 switch 语句或类似的语句 - 例如@Brandon Yates 的建议,我可能会挑剔

【问题讨论】:

  • 如果只使用 20 个元素,为什么第一个数组需要 120 个元素?
  • 因为我需要查找给定 Ascii 值的位图,该值可能高达 128
  • 那么没有定义位图的字符会发生什么?
  • 一切都会崩溃并可怕地燃烧:)
  • 如果字符串是硬编码的,将实际使用的ASCII码重新映射到一个连续的范围内。

标签: c arrays data-structures ascii lookup-tables


【解决方案1】:

像这样的结构数组呢

typedef struct
{
    uint8_t asciiCode;
    uint8_t bitmap;
} charMapping_t;

然后像这样初始化它

const static charMapping_t myMap[20] = {your 20 chars....}

【讨论】:

  • 但这需要 O(n) 次操作,必须遍历结构数组才能找到给定的字符。我想 20 次迭代还不错,但我更喜欢更优化的东西。不过谢谢!
  • 您应该在原始问题中更清楚地列出您的要求。我猜这是学校作业?我从未见过无法通过循环节省 100 字节或 20 次迭代的真实应用程序。 (实际上平均可能是 10 次迭代),如果你知道字符的频率,你可以将它优化到小于这个值。
  • 我一直在将廉价组件推向极限,并且几乎在机器代码级别进行优化,我在合理范围内尽可能优化,而不必重新访问,但你是对的, 在这种情况下这可能是 OTT
  • 也许你可以用实际的 6 字节位图替换索引,再节省 20 字节......
【解决方案2】:

所以像下面这样的东西效率不够:

struct bitmap {
    char byte[6];
};

char charset[] = "0123456789+-*/;.";

/* initialize the glyphs in the same order as charset, use glyph[0] for unknown ascii */
const struct bitmap map[sizeof(charset)+1] = { 
    { }, /* unknown glyph */
    { }, /* glyph for 0 */
    { }, /* glyph for 1 */
    ...
    { }, /* glyph for + */
    { }, /* glyph for - */
    ...
    { }, /* glyph for . */
};

/* return the appropriate map */
static inline const struct bitmap const * get_bitmap(char ascii) {
      char *p = strchr(charset, ascii);
      if ( p ) {  return &map[(p - charset) + 1]; }
      return &map[0];
}

【讨论】:

    【解决方案3】:

    对于 12 个字节,如果您有字符 n 的图形位图(其中 32 n 为 1。将打包的位图存储在字节数组中(使用结构时要小心,因为您可能不得不担心元素之间的填充)。

    您的代码将如下所示。 get_bitmap 代码幼稚而缓慢,但会编译成小东西。

    const unsigned char bitmap_available[12] = {0x1, 0x23, ...};
    const unsigned char bitmaps[] = {
        0x0, 0xff, 0x0, 0xff, 0x0, 0xff,  // first character
        0x1, 0x1, 0x1, 0x1, 0x1, 0x1, // second character
        ...
    };
    
    /* Do we have bitmap data available for character c? */
    int char_available(char c) {
        if (c < 32 || c > 127) return 0;
        c -= 32;
        return (bitmap_available[c >> 3] >> (c & 7)) & 1;
    }
    
    /* Returns pointer to bitmap for character c, or NULL if it's not present. */
    const unsigned char *get_bitmap(char c) {
        int i, n = 0;
        if (!char_available(c)) return 0;
        for (i = 32; i < c; i++) {
            n += char_available(i);
        }
        return bitmaps + n * 6;
    }
    

    显然我不知道你要哪个字符,也没有你的位图,所以我在两个数据数组中放了一些随机数据作为例子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多