I have a string s = "if man was meant to stay on the ground god would have given us roots"
.
I removed spaces and had "ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots"
.
Now I want to push the characters of the string into a 2d vector of 7 rows and 8 columns. The output should look like:
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots
I tried the following method but wasn't working.
void encryption(string s)
{
const int rows = 7;
const int colums = 8;
vector<vector<char>> v;
for (int i = 0; i < rows; i++)
{
vector<char>temp;
for (int j = 0; i < colums; j++)
{
temp.push_back(s[0]);
s.erase(0);
}
v.push_back(temp);
}
for (int i = 0; i < v.size(); i++)
{
for (int j = 0; j < v[i].size(); j++)
cout << v[i][j];
}
}
There are several issues with your code:
1) Wrong index variable used in the loop here:
for (int j = 0; i < colums; j++)
2) The std::vector::erase
function takes an iterator as the argument, not a position.
3) Even if you fix the loop mentioned in 1), you do not check to see if you're at the end of the string.
4) Your final output does not output carriage returns, making the output look "wrong".
Given the string you used, making the appropriate changes, the code could look like this:
#include <string>
#include <vector>
#include <iostream>
using namespace std;
void encryption(string s)
{
const int rows = 7;
const int colums = 8;
vector<vector<char>> v;
for (int i = 0; i < rows; i++)
{
vector<char>temp;
for (int j = 0; j < colums && !s.empty(); j++) // <-- Note we stop the loop if the string is empty.
{
temp.push_back(s[0]);
s.erase(s.begin()); // <-- This erases the first character
}
v.push_back(temp);
}
for (size_t i = 0; i < v.size(); i++)
{
for (size_t j = 0; j < v[i].size(); j++)
cout << v[i][j];
cout << "\n"; // <-- You are missing this in your output
}
}
int main()
{
encryption("ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots");
}
Output:
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots
Given this, this is a highly inefficient in that you are erasing the first character of the string. There is no need for erasing a character for this.
Here is an alternate solution using std::vector<std::string>
, and a while
loop that keeps track of starting and ending iterators within the string:
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
void encryption(std::string s)
{
const size_t columns = 8;
std::vector<std::string> v;
// start at beginning of string
auto startIter = s.begin();
// point to either 8 characters after the start, or the end of the
// string, whichever comes first
auto endIter = startIter + std::min(columns, static_cast<size_t>(std::distance(startIter, s.end())));
while (true)
{
// just push on a string using the start and end iterators
v.push_back({startIter, endIter});
// if the end iterator is at the end of the string, quit
if (endIter == s.end())
break;
// move the start to the end
startIter = endIter;
// move the end to either 8 characters after the start, or the
// end of the string, whichever comes first
endIter = startIter + std::min(columns, static_cast<size_t>(std::distance(startIter, s.end())));
}
// Output the results
for (auto& vrow : v)
std::cout << vrow << "\n";
}
int main()
{
encryption("ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots");
}
Output:
ifmanwas
meanttos
tayonthe
groundgo
dwouldha
vegivenu
sroots