将ASCII转换为Unsigned Int,反之亦然



我正在读取一个每行有几个不同字段的大文件。通过类比,您可以将文件的每行视为代表一名员工,其中一个字段包含他们工作的部门名称。但是,部门名称可以由任意4-5个ASCII字符组成(例如:"1234", "ABCD", "P+0$i"

目前,我(天真地)将字符存储为std::string,但我注意到我已经执行了很多耗时的字符串比较。因此,我想从文件中读取字段,将字符串转换为数字(可能是无符号int?),然后再进行许多数值比较(并避免字符串比较)。当然,我需要一种方法将数字转换回字符串以供输出。

我的大多数在线搜索都显示"将字符串转换为数字",它讨论了使用stringstream将数字字符串转换为某种类型的int的使用。这不是特别有帮助,我似乎不能拿出一个适当的搜索查询找到一个解决方案。有人能告诉我相关的来源或提供一种方法来执行这种转换吗?

嗯,如果你有多达5个ASCII字符,那么最简单的方法是用你喜欢的字符填充到8,然后是*reinterpret_cast<uint64_t*>(the_id.data())

如果你想让字符表示适合32位int,你需要做更多的工作:简单地丢弃高阶位(可能是因为ASCII码是0-127)仍然留下7*5 = 35位-对于32位类型来说太多了。假设id不包含任何控制代码(即ASCII码0-31),您可以像这样实现base-96编码的打包:

unsigned base = 128 - 32;
// pad c out to 5 characters if necessary.
unsigned idnum = (((((c[0] - 32) * base + (c[1] - 32)) * base + (c[2] - 32)) * base + (c[3] - 32)) * base + (c[4] - 32)) * base + c[5] - 32;

你可能会发现使用循环更容易阅读:

unsigned idnum = 0;
for (size_t i = 0; i < 5; ++i)
{
    idnum *= base;
    idnum += c[i] - ' ';
}

使用% base将数字解包回字符串值以获得最后一位数字,然后使用/ base准备获得下一个....

  1. 创建一个具有部门名称->整数映射的映射。根据部门名称的固定程度,可以从配置文件中读取它们,也可以静态地定义映射。在需要时,创建反向映射以映射integer -> string。
  2. 在读取文件时,查找映射中的关联键并将其存储在数据结构中。
  3. 当需要时,在反向映射中查找部门名称

考虑到std::string相等操作对于任意长度的数据实际上是有效的,并且您需要保留实际的字符串值,我觉得您可能需要在其他地方寻找性能改进。查看您的需求,看起来您只需要为您的对象提供更好的搜索效率。std::unordered_map容器可能是一个很好的备选方案。它是一个关联容器,通过键进行查找的时间是恒定的。您可以将数据的其他集合存储为unordered_map的值类型,并将关联键设置为您想要查找的键。下面是一些类型的示例,这些类型支持通过字符串查找数据的匹配子集。

struct Employee;
typedef std::vector<std::shared_ptr<Employee>> Employees;
typedef std::unordered_map<std::string, Employees>  EmployeeByLookup;

然后您可以像这样查找匹配给定键值的所有员工。

static EmployeeByLookup byDepartment;
Employees& GetDepartmentList(const std::string& department)
{
    return byDepartment[department];
}

如果您需要通过值而不是通过关联键查找对象,那么我建议您查看std::unordered_set。它还具有查找时间为常数的平均复杂度。如果需要优化内部哈希性能,可以为对象创建自己的哈希函数。

我使用unordered_map示例创建了一个简单的应用程序。如果你感兴趣的话可以看一下

c++ 11有std::stoi。除此之外,还可以使用stringstream进行转换:

std::istringstream iss("1234");
int x;
if ( iss >> x )
    std::cout << "Got " << x << "n";
else
    std::cout << "String did not contain a numbern";

您可以从iss中执行其他流提取,就像您习惯使用cin一样。

我不知道为什么你认为stringstream建议"不是很有用"?

相关内容

  • 没有找到相关文章

最新更新