Replace data in 2D vector C++ - c++

I am trying to search a 2D vector for a char, namely a '?' and replace it with 'x'.
I have no issues doing this task with a single vector but keep having issues with the a 2D vector implementation, see below for code.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// An empty vector of vectors
vector<vector<char> > v2d;
// Create a vector with 5 elements
vector<char> v2(5, '?');
// Create a vector of 3 elements.
vector<vector<char> > v2d2(3, v2);
// Print out the elements
cout << "Before Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
cout << v2d2[i][j] << " ";
cout << endl;
}
cout << "" << endl;
/* Does not work as expected
cout << "Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
{
if (v2d[i] == '?');
(v2d[i] = 'x');
}
}
*/
cout << "" << endl;
cout << "After Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
cout << v2d2[i][j] << " ";
cout << endl;
}
system("pause > NULL");
return 0;
}
I receive the error message below when I try and compile the code.
IntelliSense: no operator "==" matches these operands operand types are: std::vector>, std::allocator>>> == char Project3\Source.cpp 77 16 Project3
I believe it is an issue with the container in updating the proper row and column. Any help would be much appreciated.
Thank you

There were a few bugs, please compare with your original code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// An empty vector of vectors
vector<vector<char> > v2d;
// Create a vector with 5 elements
vector<char> v2(5, '?');
// Create a vector of 3 elements.
vector<vector<char> > v2d2(3, v2);
// Print out the elements
cout << "Before Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
cout << v2d2[i][j] << " ";
cout << endl;
}
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
if (v2d2[i][j] == '?')
v2d2[i][j] = 'x';
}
cout << "After Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
std::cout << v2d2[i][j] << " ";
cout << endl;
}
return 0;
}

Take a look at your commented code:
cout << "Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
{
if (v2d[i] == '?'); // <------
(v2d[i] = 'x');
}
}
There is a semi-colon after the if statement, meaning that nothing will be executed if the statement is true. Rookie mistake.
Many consider it a bad practice not to always use parentheses with if-statements and other similar situations that require them, because of issues like this one

You should have :
if (v2d[i][j] == '?'){
v2d[i][j] = 'x';
}

cout << "Vector Update" << endl;
for (int i = 0; i < v2d2.size(); i++) {
for (int j = 0; j < v2d2[i].size(); j++)
{
if (v2d[i][j] == '?')
v2d[i][j] = 'x';
}
}
You were not accessing the 2d vector correctly, should have used v2d[i][j] instead.

Related

Display first even and then odd elements in a C++array

I'm a C++ newb. I need to insert numbers to an array and then display first the odd numbers and then the even numbers in a single array. I've managed to create two separate arrays with the odd and even numbers but now I don't know how to sort them and put them back in a single array. I need your help to understand how to do this with basic C++ knowledge, so no advanced functions. Here's my code:
#include <iostream>
using namespace std;
int main()
{
int N{ 0 }, vector[100], even[100], odd[100], unify[100], i{ 0 }, j{ 0 }, k{ 0 };
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++) {
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++) {
if (vector[i] % 2 == 0) {
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0) {
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++) {
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++) {
cout << " " << odd[i] << " ";
cout << endl;
}
return 0;
}
If you don't need to store the values then you can simply run through the elements and print the odd and the even values to different stringstreams, then print the streams at the end:
#include <sstream>
#include <stddef.h>
#include <iostream>
int main () {
std::stringstream oddStr;
std::stringstream evenStr;
static constexpr size_t vecSize{100};
int vec[vecSize] = {10, 5, 7, /*other elements...*/ };
for(size_t vecIndex = 0; vecIndex < vecSize; ++vecIndex) {
if(vec[vecIndex] % 2 == 0) {
evenStr << vec[vecIndex] << " ";
} else {
oddStr << vec[vecIndex] << " ";
}
}
std::cout << "Even elements are:" << evenStr.rdbuf() << std::endl;
std::cout << "Odd elements are:" << oddStr.rdbuf() << std::endl;
}
Storing and sorting the elements are always expensive.
Basically, it would be better to sort them first.
#include <iostream>
using namespace std;
int main()
{
int numbers[5];
int mergedArrays[5];
int evenNumbers[5];
int oddNumbers[5];
for(int i=0;i<5;i++){
cin>>numbers[i];
}
int temp=numbers[0];
//bubble sort
for(int i = 0; i<5; i++)
{
for(int j = i+1; j<5; j++)
{
if(numbers[j] < numbers[i])
{
temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
int nEvens=0;
int nOdds=0;
for(int i = 0; i<5; i++)
{
if(numbers[i]%2==0)
{
evenNumbers[nEvens]=numbers[i];
nEvens++;
}
else if(numbers[i]%2!=0)
{
oddNumbers[nOdds]=numbers[i];
nOdds++;
}
}
int lastIndex=0;
//copy evens
for(int i = 0; i<nEvens; i++)
{
mergedArrays[i]=evenNumbers[i];
lastIndex=i;
}
//copy odds
for(int i =lastIndex; i<nOdds; i++)
{
mergedArrays[i]=oddNumbers[i];
}
return 0;
}
If you have to just output the numbers in any order, or the order given in the input then just loop over the array twice and output first the even and then the odd numbers.
If you have to output the numbers in order than there is no way around sorting them. And then you can include the even/odd test in the comparison:
std::ranges::sort(vector, [](const int &lhs, const int &rhs) {
return ((lhs % 2) < (rhs % 2)) || (lhs < rhs); });
or using a projection:
std::ranges::sort(vector, {}, [](const int &x) {
return std::pair<bool, int>{x % 2 == 0, x}; });
If you can't use std::ranges::sort then implementing your own sort is left to the reader.
I managed to find the following solution. Thanks you all for your help.
#include <iostream>
using namespace std;
int main()
{
int N{0}, vector[100], even[100], odd[100], merge[100], i{0}, j{0}, k{0}, l{0};
cout << "Add the dimension: " << endl;
cin >> N;
cout << "Add the elements: " << endl;
for (int i = 0; i < N; i++)
{
cout << "v[" << i << "]=" << endl;
cin >> vector[i];
}
for (i = 0; i < N; i++)
{
if (vector[i] % 2 == 0)
{
even[j] = vector[i];
j++;
}
else if (vector[i] % 2 != 0)
{
odd[k] = vector[i];
k++;
}
}
cout << "even elements are :" << endl;
for (i = 0; i < j; i++)
{
cout << " " << even[i] << " ";
cout << endl;
}
cout << "Odd elements are :" << endl;
for (i = 0; i < k; i++)
{
cout << " " << odd[i] << " ";
cout << endl;
}
for (i = 0; i < k; i++)
{
merge[i] = odd[i];
}
for (int; i < j + k; i++)
{
merge[i] = even[i - k];
}
for (int i = 0; i < N; i++)
{
cout << merge[i] << endl;
}
return 0;
}
You can use Bubble Sort Algorithm to sort whole input. After sorting them using if and put odd or even numbers in start of result array and and others after them. like below:
//Bubble Sort
void bubbleSort(int arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already
// in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
// Insert In array
int result[100];
if(odd[0]<even[0])
{
for (int i = 0; i < k; i++)
{result[i] = odd[i];}
for (int i = 0; i < j; i++)
{result[i+k] = even[i];}
}else
{
for (int i = 0; i < j; i++)
{result[i] = even[i];}
for (int i = 0; i < k; i++)
{result[i+k] = odd[i];}
}

How can I remove the lines being output in my 2d array?

When I run the program, I get lines in between the elements of my 2d array.
How do I get rid of them? I meant to have empty values
cout << " ";
for (int i = 0; i < 10; i++)
cout << i << " ";
cout << endl;
for (int i = 0; i < 10; i++)
{
cout << i << " ";
for (int j = 0; j < 10; j++)
{
cout << grid[i][j] << " ";
}
cout << endl;
}
Doing char grid[MAX_ROWS][MAX_COLS]; is not an initialization, it just creates the grid with garbage inside it. If you want to have empty spaces you have to do something like:
for (size_t i = 0; i < MAX_ROWS; i++) {
for(size_t j = 0; j < MAX_COLS; j++) {
grid[i][j] = ' ';
}
}

Having trouble sorting my array. Why won't my array sort properly?

My program needs to read in the size of an array from the command line, it then should fill the array with random numbers. It should then display the sorted and unsorted contents of the array.
Created one for loop in order to read random numbers into the array and to display unsorted contents. Created a second for loop nested in the first one in order to sort the contents within the array.
#include <time.h>
#include <iostream>
#include <iomanip>
#include <cstdlib>
using namespace std;
int main(int argc, char * argv[], char **env)
{
int SIZE = atoi(argv[1]);
int *array = new int[SIZE];
for(int i = 0; i < SIZE; i++)
{
array[i] = rand()% 1000;
cout << i << ": " << array[i] << "\n";
for(int j = 0; j < SIZE; j++)
{
if(array[j] > array[j + 1])
{
swap(array[j], array[j +1]);
}
cout << i << ": " << array[i] << "\n";
}
}
return 0;
}
I expect an output like
0: 350
1: 264
2: 897
0:264
1:350
2:897
I'm getting an output like
0:41
0:41
0:41
0:41
1:46
1:46
1:0
1:0
2:334
2:334
2:334
2:334
Because you are attempting to continually sort the array before it's initialized. Also, you have undefined behavior when j == SIZE-1 because it's illegal to compare array[j] > array[j+1] at that point. array[j+1] is an invalid index.
Instead of this:
for(int i = 0; i < SIZE; i++)
{
array[i] = rand()% 1000;
cout << i << ": " << array[i] << "\n";
for(int j = 0; j < SIZE; j++)
{
if(array[j] > array[j + 1])
{
swap(array[j], array[j +1]);
}
cout << i << ": " << array[i] << "\n";
}
}
This instead:
// randomly initialize the array
for(int i = 0; i < SIZE; i++)
{
array[i] = rand()% 1000;
cout << i << ": " << array[i] << "\n";
}
// sort
for (int i = 0; i < SIZE; i++)
{
for(int j = i+1; j < SIZE; j++)
{
if(array[i] > array[j])
{
swap(array[i], array[j]);
}
}
}
// print results
cout << "finished sorting" << endl;
for(int i = 0; i < SIZE; i++)
{
cout << i << ": " << array[i] << "\n";
}
The immediate issue is that your code is attempting to sort the array even before it's been fully initialized.
You need to split your main loop into three:
the first one to initialize the array;
the second one to sort the array (this would include an inner loop used by bubble sort);
the third one to print the results.
Separately, you also need to think carefully about the boundary conditions of your loops.

Difference of 2 sets retained in arrays - C++

Consider two sets retained in two arrays. Find the union, intersection and difference (relative complement) of the two sets.
I managed to solve the union and the intersection, but the difference is giving me a hard time. Any hints? And if possible, keep it as simple as possible, without functions or more complex aspects, because I'm a beginner and I still have a lot to learn.
Thank you in advance!
#include <iostream>
using namespace std;
int main()
{
int v1[100], v2[100], u[200], intersection[100], d[100];
unsigned int v1_length, v2_length, i, j, OK = 0, union_length;
cout << "Enter the number of elements of the first array:" << " ";
cin >> v1_length;
cout << "Enter the elements of the first array:" << '\n';
for (i = 0; i < v1_length; i++)
cin >> v1[i];
cout << "Enter the number of elements of the second array:" << " ";
cin >> v2_length;
cout << "Enter the elements of the second array:" << '\n';
for (i = 0; i < v2_length; i++)
cin >> v2[i];
//Union
union_length = v1_length;
for (i = 0; i < v1_length; i++)
u[i] = v1[i];
for (i = 0; i < v2_length; i++)
{
int ok = 0;
for (j = 0; !ok && j < v1_length; j++)
if (v1[j] == v2[i])
ok = 1;
if (!ok)
{
u[union_length] = v2[i];
union_length++;
}
}
cout << "The union of the two sets contained in the arrays is: ";
for (i = 0; i < union_length; i++)
cout << u[i] << " ";
cout << '\n';
//Intersection
unsigned int k = 0;
cout << "The intersection of the two sets contained in the arrays is: ";
for (i = 0; i < v1_length; i++)
for (j = 0; j < v2_length; j++)
if (v1[i] == v2[j])
{
intersection[k] = v1[i];
k++;
}
for (i = 0; i < k; i++)
cout << intersection[i] << " ";
cout << '\n';
//Difference
unsigned int l = 0, OK2 = 0;
cout << "The difference of the two sets contained in the arrays is: ";
for (i = 0; i < v1_length; i++)
{
for (j = 0; j < v2_length; j++)
{
if (v1[i] == v2[j])
OK2 = 1;
if (!OK2)
{
d[l] = v1[i];
l++;
}
}
}
for (i = 0; i < l; i++)
cout << d[i] << " ";
cout << '\n';
return 0;
}
It seems that the intersection is the best place to start. You want the items that only in appear in one of the two arrays, right?
So, for the inner loop, you need to compare all the elements. Then, if no match was found, you have the a unique element.
You need to add the curly braces {} to the for loop. I know that curly braces are distracting at times, but over time, you will probably find it safer to almost always include them to avoid confusion.
for (i = 0; i < v1_length; i++)
for (j = 0; j < v2_length; j++) {
if (v1[i] == v2[j]){
break; // this item is not unique
} else if(j == v2_length - 1){
d[l] = v1[i]; // This is the unique one, add it to the answer array
l++;
}
}
for (i = 0; i < l; i++)
cout << intersection[l] << " ";
cout << '\n';
You're on the right track!
You're doing a few things wrong. Here are some fixes you can try:
Only set OK2 to 0 once per inner-loop
Reset OK2 to 0 at the end of the inner-loop
Only do the insertion into d after the inner-loop has completed
As an optimization, consider breaking after you set OK2 to 1, as you know at that point it can never be set to 0 for the current value pointed to by the outer-loop.

C++ Grid Issues

I'm printing random numbers enclosed in ascii boxes in a 6x6 grid. Having issues with printing out the grid.
Instead of having 6 columns, all my boxes and numbers are being printed out in 1 column. Been troubleshooting but cant seem to find the issue. Below is the code. Appreciate your assistance.
int main(void)
{
cout << "Magic Grid\n" << endl;
int arrayxy [6][6];
srand((unsigned)time(0));
int lowest=1111, highest=9999;
int range=(highest-lowest)+1;
// Fill array with random values
for (int i = 0; i < 6; ++i)
{
for(int j = 0; j < 6; ++j)
{
arrayxy[i][j] = lowest+int(range*rand()/(RAND_MAX + 1.0));
}
}
// Print array as grid
for (int i = 0; i < 6; ++i)
{
for(int j = 0; j < 6; ++j)
{
cout << char(218);
for (int y=0; y< 4; y++)
{
cout << char(196);
}
cout << char(191) <<endl;
cout << char(179) << arrayxy[i][j] << char(179) << endl;
cout << char(192);
for (int z=0; z< 4; z++)
{
cout << char(196);
}
cout << char(217) <<endl;
}
cout << endl;
}
cout << endl;
}
You should endl after all the columns get printed out, NOT before.
This is how I fixed your code that gives, hopefully, what you wanted to have.
For the record, I specifically changed those ASCII to * and & to make the console result more readable. You can change them back to what you want those characters to be again.
void WriteFrontLine(std::size_t count)
{
for (int i = 0; i < count; i++)
{
cout << '*';
cout << '&' << '&' << '&' << '&';
cout << '*';
}
cout << endl;
}
void WriteEndLine(std::size_t count)
{
for (int i = 0; i < count; i++)
{
cout << '*';
cout << '&' << '&' << '&' << '&';
cout << '*';
}
cout << endl;
}
int main(void)
{
cout << "Magic Grid\n" << endl;
int arrayxy[6][6];
srand((unsigned)time(0));
int lowest = 1111, highest = 9999;
int range = (highest - lowest) + 1;
// Fill array with random values
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 6; ++j)
{
arrayxy[i][j] = lowest + int(range*rand() / (RAND_MAX + 1.0));
}
}
// Print array as grid
for (int i = 0; i < 6; ++i)
{
WriteFrontLine(6);
for (int j = 0; j < 6; ++j)
{
cout << '*' << arrayxy[i][j] << '*';
}
cout << endl;
WriteEndLine(6);
cout << endl;
}
cout << endl;
}