I have a problem, let's assume I have a string
std::string str = "some_characters_here";
and I have a vector with numbers from 0 to 255
std::vector<int> v;
How can I map each number to closest char in string? like this
function map (number) -> char in string perfect if we can do str[n]
so I have a string len
, and I can count this:
int n = 255 / str.length();
But I have no idea what to do next.
Each character in the string now has a weight, the only thing left is to figure out how to give each number a symbol (let's say the number is on the range from symbol-1 to symbol, then give it a symbol)
Here is another example:
CodePudding user response:
Although the question is not very clear, as I understand it, you want to divide an array with a size of 255 into ranges according to the length of a string and assign the string's characters to those ranges.
std::vector<char> __map(const std::string &str)
{
std::vector<char> result(256);
float n = (float)256 / str.size(), iter = n;
int id = int(n), loopIndex = 0;
size_t strIndex = 0;
while (id < 256)
{
for (; loopIndex < id; loopIndex)
result[loopIndex] = str[strIndex];
strIndex;
iter = n;
id = (int)iter;
}
if (loopIndex < 256)
for (; loopIndex < 256; loopIndex)
result[loopIndex] = str[strIndex];
return result;
}
As in the example above, we have pushed the array according to the string length, assigning the characters in the index of the string to the ranges.
int main()
{
const std::string s = ".^&@$!%";
auto rr = __map(s);
for (size_t i = 0; i < rr.size(); i )
std::cout << i << " : " << rr[i] << '\n';
return 0;
}
One of the points that is not understood here is this; if you want to keep the characters, you need to use std::vector here, but you used an int type vector in your description. Do you want to keep the code of the characters in the vector?
Now let's look at the problem from a different aspect. Instead of keeping the characters in the series, let's return this structure in the form of a series by keeping the beginning and end of a structure and the value of the character.
struct RangeforChar
{
uint8_t start;
uint8_t end;
char value;
RangeforChar(uint8_t start, uint8_t end, char value) : start(start), end(end), value(value) {}
};
std::vector<RangeforChar> _map(const std::string &str)
{
std::vector<RangeforChar> res;
float n = (float)256 / str.size(), iter = n;
int first = 0, last = 0, id = int(n);
size_t strIndex = 0;
while (id < 256)
{
last = id;
res.emplace_back(first, last, str[strIndex ]);
iter = n;
id = (int)iter;
first = last;
}
res.emplace_back(first, 255, str[strIndex ]);
return res;
}
int main()
{
const std::string s = ".^&@$!%";
auto rr = _map(s);
for (const auto& m: rr)
std::cout << "Range : " << m.start << " - " << m.end << " --> " << m.value << '\n';
return 0;
}
Output:
Range : 0 - 36 --> .
Range : 36 - 73 --> ^
Range : 73 - 109 --> &
Range : 109 - 146 --> @
Range : 146 - 182 --> $
Range : 182 - 219 --> !
Range : 219 - 255 --> %
We can write a helper method that returns a character from a string.
char h_get(const std::vector<RangeforChar>& rng, int num)
{
for (const auto& m: rng)
if(num < m.end) return m.value;
throw std::domain_error("An unexpected error has occurred in the program.");
}
char _get(const std::string& str, int num)
{
assert(num >= 0 && num <= 255);
auto rr = _map(str);
return h_get(rr, num);
}
const std::string s = ".^&@$!%";
std:: cout << "Char is " << _get(s, 167);