Home > Net >  Storing all vector values in a data type
Storing all vector values in a data type

Time:10-08

I have a vector declared containing n integers.

vector <int> tostore[n];

I want to store all the numbers in the vector inside a string in the format of their subscripts, like 12345..n

Example:

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;

Desired Output:

12345

How do I store it in store_str without printing it?

CodePudding user response:

One way would be to just multiply by 10 each iteration

int result = 0;

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

As mentioned in comments, a more robust approach would be concatenating to an actual string, or at least using a 64-bit integer.

CodePudding user response:

Instead of using an integer, which if it is 32 bits wide will only be able to store 8-9 digits, you could instead build a string that has all of the elements combined like

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"

CodePudding user response:

Since you confirmed that store_vec only contains single digit numbers, a simple way of doing this would be :

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());

or basically use the str resulting with accumulate since it already represent the sequence.

CodePudding user response:

Since you know that each value in tostore will only be a single digit, you could use int_8 or uint8_t data types to store the values instead. This way you can still perform arithmetic on the values within the vectors (so long as the result of the arithmetic falls within the range of -128 to 127 or 0 to 255 respectively, see integer types for more details). These data types have the advantage of being only a single byte long, allowing your vector to potentially be more densely packed and faster to traverse. You can then use std::cout << unsigned(tostore[n]) to cast the integer into a character for display. The whole thing would look something like this

#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]);
    }
}

Alternatively, if you know that your digit will always be positive it opens a whole new range of possibilities. When converting an integer to a list of characters a program needs to break the integer into its individual digits and then add 48 to that digits value to find its ascii character code equivalent (see asciiTable for more details). The process of splitting the integer into its base 10 digits may be too cumbersome (you decide) if you plan to display these characters often or perform only a few arithmetic operations on the data. In this case you could create a struct that stores the value of the integer as a char data type but performs arithmetic with the data as if it were an integer. This way, when printing the values no operations need to be performed to format the data properly and the only operations that need to be done to format the data for arithmetic operations are simple subtractions by 48 which are very fast. Such a struct could look something like this:

#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());
}

Now this might not be what you are looking for, but I hope that it does showcase an important aspect of programming which is "the more you know about the data you are working with, the more you can optimize the program" so make sure you have a good feel for the range of the data you are working with and what operations you are going to be doing with it most often (arithmetic or printing for example) and the cost of those operations.

  • Related