繁体   English   中英

将所有向量值存储在一个数据类型中

[英]Storing all vector values in a data type

我有一个向量声明包含 n 个整数。

vector <int> tostore[n];

我想将向量中的所有数字以其下标的格式存储在一个字符串中,例如 12345..n

例子:

vector <int> store_vec{1,2,3,4,5};
int store_str;     //to store the digits in order from vector store_vec
cout<<store_str;

所需 Output:

12345

如何在不打印的情况下将其存储在 store_str 中?

不是使用 integer,如果它是 32 位宽将只能存储 8-9 位数字,您可以构建一个包含所有元素的字符串,例如

vector <int> store_vec{1,2,3,4,5};
std::string merged;
merged.reserve(store_vec.size());
for (auto num : store_vec)
    merged += '0' + num;
// now merged is "12345"

一种方法是每次迭代仅乘以10

int result = 0;

for (auto it : tostore)
{
    result = result * 10 + it;
}

正如评论中提到的,一种更可靠的方法是连接到实际字符串,或者至少使用 64 位 integer。

由于您知道tostore中的每个值都只会是一个数字,因此您可以使用int_8uint8_t数据类型来存储这些值。 这样您仍然可以对向量中的值执行算术运算(只要算术运算的结果分别落在-128 to 1270 to 255的范围内,请参阅integer 类型了解更多详细信息)。 这些数据类型的优点是只有一个字节长,使您的向量可能更密集,遍历速度更快。 然后,您可以使用std::cout << unsigned(tostore[n])将 integer 转换为要显示的字符。 整个事情看起来像这样

#include <iostream>
#include <type_traits>
#include <vector>

int main()
{
    std::vector<uint8_t> tostore;
    tostore.reserve(32);

    for(int i = 0; i < 32; ++i) {
        tostore.push_back(i % 10);
    }

    for(uint i = 0; i < tostore.size(); ++i) {
        std::cout << unsigned(tostore[i]);
    }
}

或者,如果您知道您的数字将始终为正数,那么它会打开一个全新的可能性范围。 将 integer 转换为字符列表时,程序需要将 integer 分解为各个数字,然后将 48 添加到该数字值以找到其等效的 ascii 字符代码(有关更多详细信息,请参见asciiTable )。 如果您计划经常显示这些字符或仅对数据执行少量算术运算,则将 integer 拆分为其基数 10 位数字的过程可能过于繁琐(由您决定)。 在这种情况下,您可以创建一个struct ,将 integer 的值存储为char数据类型,但对数据执行算术,就好像它是 integer 一样。这样,在打印值时无需执行任何操作来格式化数据正确地为算术运算格式化数据所需要做的唯一操作是简单地减去 48,这是非常快的。 这样的结构看起来像这样:

#include <iostream>
#include <type_traits>
#include <vector>

struct notANumber {
    char data;

    notANumber() {}

    notANumber(const int& a) : data(a + 48) {}

    notANumber(const char& a) : data(a) {}

    notANumber operator+(const notANumber& b) {
        notANumber c;
        c.data = b.data + c.data - 48;
        return c;
    }

    notANumber operator-(const notANumber& b) {
        notANumber c;
        c.data = b.data - c.data + 48;
        return c;
    }

    notANumber operator*(const notANumber& b) {
        notANumber c;
        c.data = (b.data - 48) * (c.data - 48) + 48;
        return c;
    }

    notANumber operator/(const notANumber& b) {
        notANumber c;
        c.data = (b.data - 48) / (c.data - 48) + 48;
        return c;
    }
};

int operator+(const int& a, const notANumber& b) {
    int c;
    c = a + b.data - 48;
    return c;
}

int operator-(const int& a, const notANumber& b) {
    int c;
    c = a - b.data + 48;
    return c;
}

int operator*(const int& a, const notANumber& b) {
    int c;
    c = a * (b.data - 48);
    return c;
}

int operator/(const int& a, const notANumber& b) {
    int c;
    c = a / (b.data - 48);
    return c;
}



int main()
{
    std::vector<notANumber> tostore;
    tostore.reserve(32);

    for(int i = 0; i < 32; ++i) {
        tostore.push_back(i % 10);
    }

    std::cout.write(reinterpret_cast<char*>(tostore.data()), tostore.size());
}

现在这可能不是您要找的东西,但我希望它确实展示了编程的一个重要方面,即“您对正在使用的数据了解得越多,您就越能优化程序”,因此请确保您对您正在处理的数据范围以及您最常对其进行的操作(例如算术或打印)以及这些操作的成本有一个很好的了解。

由于您确认store_vec仅包含单个数字,因此一种简单的方法是:

std::vector<uint8_t> store_vec = {1,2,3,4,5};
std::string str = std::accumulate(store_vec.begin(), store_vec.end(), std::string{}, 
        [](const std::string& res, uint8_t num){ return res + char('0' + num); });
int resnum = atoi(str.c_str());

或者基本上使用str结果与 accumulate 因为它已经代表了序列。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM