I have a constructor and a method in an implementation file:
Boggle::Boggle(std::string boardString){
dim = sqrt(boardString.size());
vector<vector<char> > grid(dim, vector<char>(dim));
int co = 0;
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe() {
for (auto inner : grid)
{
for (auto item : inner)
{
cout << item << " ";
}
cout << endl;
}
}
The program executes, but doesn't do anything. As you can see I have sized my vector when I declared it. I believe the issue lies in my logic of assigning a character to a vector from a string perhaps.
As hinted in comments your vector grid is local to your function. You mostly likely wanted to use a class variable but ended up creating a local variable. You can use resize to set the dimensions of your grid. Also its better to ceil the sqrt to make sure that we are not missing any characters.
Example:
#include <stdio.h>
#include <vector>
#include <string>
#include <cmath>
#include <iostream>
using namespace std; // Avoid this
class Boggle{
public:
int dim;
vector<vector<char>> grid;
Boggle(string boardString);
void printMe();
};
Boggle::Boggle (std::string boardString)
{
dim = ceil(sqrt(boardString.size ()));
grid.resize(dim, vector <char>(dim));
int co = 0;
for (int i = 0; i < dim; i++) {
for (int j = 0; j < dim; j++)
{
grid[i][j] = boardString[co];
co++;
}
}
}
void Boggle::printMe ()
{
for (auto inner:grid) {
for (auto item:inner)
{
cout << item << " ";
}
cout << endl;
}
}
int main(){
Boggle boggle("hello world");
boggle.printMe();
return 0;
}
Result:
h e l l
o w o
r l d
Related
I have some code written but I'm not sure why the reversed array is not giving me the exact values I need. I created a second array the same size as the first and used nested for loops to fill the second with the contents of the first in reverse.
See below:
#include <iostream>
using namespace std;
int main()
{
// Ask for how big the array is
int n;
cout << "how big is the array?" << endl;
cin >> n;
// create array
int a[n];
// create second array
int b[n];
// ask for contents of the 1st array
cout << "what's in the array?" << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
// reverse the array
for (int i = n - 1; i >= 0; i--)
{
for (int k = 0; k < n; k++)
{
b[k] = a[i];
break;
}
}
// print out the new array
for (int k = 0; k < n; k++)
{
cout << b[k] << endl;
}
return 0;
}
you don't need 2 bucles for fill the second array
try with:
//reverse the array
s = 0;
for (int i=n-1;i>=0;i--){
b[n]=a[s];
s++;
}
Try something like this:
#include <algorithm>
#include <iostream>
#include <vector>
namespace {
template <typename IStream>
[[nodiscard]] int readOneIntFrom(IStream& istream) {
int x;
istream >> x;
return x;
}
}
int main()
{
// Ask for how big the array is
std::cout << "how big is the array?" << std::endl;
auto n = readOneIntFrom(std::cin);
// create array
std::vector<int> a;
// ask for contents of the 1st array
std::cout << "what's in the array?" << std::endl;
for (int i = 0; i < n; i++)
{
a.emplace_back(readOneIntFrom(std::cin)); // Make a new entry at the end of a.
}
// Construct b from a backward. (Or do auto b = a; std::reverse(b.begin(), b.end());
auto b = std::vector<int>(a.rbegin(), a.rend());
// print out the new array
for (const auto& bi : b)
{
std::cout << bi << std::endl;
}
return 0;
}
First of all, im a c++ noob! Ok with that being said, i need to declare a function that initializes a grid. The function takes an array of int as the input and needs to return an array of int. I have:
array<int> InitializeGrid (array<int>)
{
const int NB_ROWS = 10;
const int NB_COLUMN = 10;
const int WATER = 0;
int grid[NB_ROWS][NB_COLONN];
for (int i = 0; i < NB_ROWS; i++)
{
for (int j = 0; j < NB_COLONN; j++)
{
grid[i][j] = WATER;
cout << grid[i][j] << " ";
}
cout << endl;
}
return ??
}
You don't need to return anything if you pass the array by reference:
#include <array>
#include <iostream>
static const int NB_ROWS = 10;
static const int NB_COLUMN = 10;
static const int WATER = 0;
void InitializeGrid (std::array<std::array<int, NB_COLUMN>, NB_ROWS> &grid)
{
for (auto &row : grid)
{
for (auto &col : row)
{
col = WATER;
std::cout << col << " ";
}
std::cout << '\n';
}
}
int main()
{
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid;
InitializeGrid(grid);
}
btw, if your WATER is 0 it is sufficive to write
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid{};
to initialize all elements to zero.
In my Intro to Computer Science class I am beginning to learn the basics of sorting algorithms. So far, we have gone over Bubble, Selection, and Insertion Sort.
After class today, the instructor has requested us to "enhance" the program by adding code to print out the vector/array after every swap during the sorting. I am at a complete loss as to how I would make this happen. I'm thinking something like :
if (swapped) { cout << vec << " "; }
but without even trying, I'm certain this wouldn't work. Any help is very much appreciated. Here's my code so far:
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> createVec(int n) {
unsigned seed = time(0);
srand(seed);
vector<int> vec;
for (int i = 1; i <= n; ++i) {
vec.push_back(rand() % 100 + 1);
}
return vec;
}
void showVec(vector<int> vec) {
for (int n : vec) {
cout << n << " ";
}
}
void bubbleSort(vector<int> &vec) {
int n = vec.size();
bool swapped = true;
while (swapped) {
swapped = false;
for (int i = 1; i <= n-1; ++i) {
if (vec[i-1] > vec[i]) {
swap(vec[i-1], vec[i]);
swapped = true;
}
}
}
}
void selectionSort(vector<int> &vec) {
int n = vec.size();
int maxIndex;
for (int i = 0; i <= n-2; ++i) {
maxIndex = i;
for (int j = i+1; j <= n-1; ++j) {
if (vec[j] < vec[maxIndex]) {
maxIndex = j;
}
}
swap(vec[i], vec[maxIndex]);
}
}
int main()
{
vector<int> numbers = createVec(20);
showVec(numbers);
cout << endl;
//bubbleSort(numbers);
selectionSort(numbers);
showVec(numbers);
return 0;
}
For example in the called function selectionSort substitute this statement
swap(vec[i], vec[maxIndex]);
for the following statement
if ( i != maxIndex )
{
swap(vec[i], vec[maxIndex]);
showVec( vec );
cout << endl;
}
Also the function showVec should declare the parameter as having a constant referenced type
void showVec( const vector<int> &vec) {
for (int n : vec) {
cout << n << " ";
}
}
This project I am writing in order to create a Square Matrix ADT object has a problem with the constructor (not the default constructor). I have traced the problem back to the constructor but I cannot figure out what is wrong with it which makes it crash everytime I try to run my test in main.cpp.
I usually get an error that say something along the lines "Thread 1: EXC_BAD_ACCESS: ..." and the console usually says "(11db)"
Does anyone have any ideas on what might be causing all the problems?
This is the header file:
#include <iostream>
#include <vector>
using namespace std;
#ifndef SquareMatrix_h
#define SquareMatrix_h
class SquareMatrix {
private:
vector<vector<double>> numMatrix;
public:
SquareMatrix();
SquareMatrix(vector<vector<double>>& v2d);
double getValue(int x, int y);
void setValue(int x, int y, double value);
friend SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2);
friend SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2);
friend ostream& operator <<(ostream &out, SquareMatrix m);
};
#endif /* SquareMatrix_h */
This is my SquareMatrix.cpp file: (The constructor that I believe isn't working is the second function in the code: SquareMatrix::SquareMatrix(vector>& v2d) {...)
#include "SquareMatrix.h"
#include <iostream>
using namespace std;
SquareMatrix::SquareMatrix() {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
SquareMatrix::SquareMatrix(vector<vector<double>>& v2d) {
bool flagSize = true;
for(int i = 0; i < v2d.size(); i++) {
if(v2d[i].size() != v2d.size()) {
flagSize = false;
break;
}
}
if(flagSize) {
numMatrix.clear();
for(int i = 0; i < v2d.size(); i++) {
vector<double> initial;
for(int j = 0; j < v2d[i].size(); i++) {
initial.push_back(v2d[i][j]);
}
numMatrix.push_back(initial);
}
} else {
numMatrix.clear();
for(int i = 0; i < 10; i++) {
vector<double> initial;
for(int j = 0; j < 10; j++) {
initial.push_back(0.0);
}
numMatrix.push_back(initial);
}
}
}
double SquareMatrix::getValue(int x, int y) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
return numMatrix[x][y];
}
return 0;
}
void SquareMatrix::setValue(int x, int y, double value) {
if((x < numMatrix.size()) && (y < numMatrix.size()) && (x >= 0) && (y >= 0)) {
numMatrix[x][y] = value;
}
}
SquareMatrix operator * (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix.size(); j++) {
initial.push_back(0);
}
result.push_back(initial);
}
for(int i = 0; i < m1.numMatrix.size(); i++) {
for(int j = 0; j < m1.numMatrix.size(); j++) {
result[i][j] = 0;
for (int a = 0; a < m1.numMatrix.size(); a++) {
result[i][j] += m1.numMatrix[i][a] + m2.numMatrix[a][j];
}
}
}
return SquareMatrix(result);
}
return SquareMatrix();
}
SquareMatrix operator - (SquareMatrix m1, SquareMatrix m2) {
if(m1.numMatrix.size() == m2.numMatrix.size()) {
vector<vector<double>> result;
for(int i = 0; i < m1.numMatrix.size(); i++) {
vector<double> initial;
for(int j = 0; j < m1.numMatrix[i].size(); j++) {
double pushNum = (m1.getValue(i,j) - m2.getValue(i,j));
initial.push_back(pushNum);
}
result.push_back(initial);
}
return SquareMatrix(result);
}
return SquareMatrix();
}
ostream& operator << (ostream &out, SquareMatrix m) {
out << "(";
for (int i = 0; i < m.numMatrix.size(); i++) {
for (int j = 0; j < m.numMatrix.size(); j++) {
out << " " << m.numMatrix[i][j];
if(j != (m.numMatrix.size() - 1)) {
out << ", ";
}
}
}
out << ")";
return out;
}
Then this is the main.cpp that I am using to test the SquareMatrix ADT object:
#include "SquareMatrix.h"
#include <iostream>
#include <random>
#include <ctime>
#include <vector>
using namespace std;
int main() {
srand(time(NULL));
vector<vector<double>> m1;
vector<vector<double>> m2;
int size = 0;
cout << "Enter the size of the Square Matrix: ";
cin >> size;
for (int i = 0; i < size; i++) {
vector<double> in1;
vector<double> in2;
for (int j = 0; j < size; j++) {
in1.push_back(rand() % 100);
in2.push_back(rand() % 100);
}
m1.push_back(in1);
m2.push_back(in2);
}
SquareMatrix res1 = SquareMatrix(m1);
SquareMatrix res2 = SquareMatrix(m2);
cout<< "\nMatrix 1: " << endl;
cout << res1 << endl;
cout<< "\nMatrix 2: " << endl;
cout << res2 << endl;
SquareMatrix mult = res1*res2;
cout << "\nMatrix1 * Matrix 2: " << endl;
cout << mult << endl;
SquareMatrix min1_2 = res1 - res2;
cout << "Matrix1 - Matrix 2: " << endl;
cout << min1_2 << endl;
SquareMatrix min2_1 = res2 - res1;
cout << "Matrix2 - Matrix 1: " << endl;
cout << min2_1 << endl;
return 0;
}
Any help you could give would be appreciated. :)
As pointed out in the comments, you problem is a simple typo in one of your nested loops. However, I'd like to add some recommendations to make your code less error prone (and also more readable).
Firstly, when iterating over all elements of a vector, unless you need an index for something else, you should be using a range-based for-loop. In your code, you might replace the check for square size with the following:
for (const vector<double>& vec: v2d){
if (vec.size() != v2d.size()){
flagSize = false;
break;
}
}
This expresses your intent a little more clearly, and, more importantly, prevents you from accidentally reading from/writing to a location out of your vector's bounds (accidentally typing <= instead of just < happens to the best of us).
Secondly, the two nested loops (that contained your error) can be replaced with a simple copy assignment (numMatrix = v2d; reference). Again, this expresses your intent in addition to being a whole lot shorter. No need to reinvent the wheel with functions like these.
The contents of the else-branch of the surrounding if-statement can also be replaced with a call to assign (the first overload listed on the page, use like numMatrix.assign(10, vector<double>(10, 0.0))). Like before, clearer expression of intent and avoidance of index errors.
Finally, the parameter in this constructor can be a const reference instead of a normal one since you do not alter its contents in any way (and, given this, it should be const).
You might wonder why "expression of intent" is relevant, or what it even means in this context. Essentially, it's all about making what you're trying to do immediately obvious to any reader. This is more important in large projects with many contributors but it is helpful even when debugging small applications like this one. You seem to be learning still, but I strongly believe it's a good thing to keep in mind from the beginning. After all, many of these changes also make for briefer code, making it that much easier for others to help you if you run into a problem.
I realize this left the scope of the original question somewhat, but I hope you find this helpful nonetheless.
I have created a 3d array into main function because one of its size came from used input. I am using C++
std::cin >> size;
typedef int T[8][3];
T* tables = new T[size];
It is basically tables[size][8][3]
Now I have to use this 3d table in different functions and have to store values into it. The best way to do it by make this table as a global variable. But I am not sure that I can do it after main function. The other option I have, that I have to pass this table as a parameter and have to return that at the end of the function.
I have tried both the approach but I am having error. Please help me about this issue. I don't know which approach to choose and how to do it.
Thank you in advance.
**Example:**This an example what I really want to do. Here I create a 3d array in main function and through another function I gave some input into that array and again print that in main function.
#include <iostream>
#include <conio.h>
using namespace std;
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
int M:: pass(int (*table)[8][3],int s)
{
for (i=0;i<s;i++)
{
//int a = tables[i][2][1];
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
table[i][j][k]=i;
}
}
}
return (*table)[8][3]; // not sure about this
}
int main()
{
int size,i,j,k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx;
mx.pass(tables,size); // not sure
for (i=0;i<size;i++)
{
for(j=0;j<8;j++)
{
for(k=0;k<3;k++)
{
cout<<tables[i][j][k];
cout<<" ";
}
cout<<endl;
}
cout<<endl;
cout<<"..........." << i <<endl;
}
getch();
}
I don't know if I completely understand your problem. But you can definitely store the pointer locally in your object and reference it elsewhere. Something like this:
class M
{
public:
M(int(*tbl)[8][3]) : table(tbl) { }
int(*table)[8][3];
int i, j, k;
public:
void pass(int size);
};
void M::pass(int s)
{
for (i = 0; i<s; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
table[i][j][k] = i;
}
}
}
}
int main()
{
int size, i, j, k;
std::cin >> size;
typedef int T[8][3]; // T is your 2d array type
T* tables = new T[size];
cout << "test";
M mx(tables);
mx.pass(size); // not sure
for (i = 0; i<size; i++)
{
for (j = 0; j<8; j++)
{
for (k = 0; k<3; k++)
{
cout << tables[i][j][k];
// or you can also:
// cout << mx.table[i][j][k];
cout << " ";
}
cout << endl;
}
cout << endl;
cout << "..........." << i << endl;
}
_getch();
}
Since you are creating a dynamic 3D array whose two dimensions are fixed, Use a std::array<std::array<int, 3>, 8> as your 2D array. Use a std::vector<__2D_ARRAY_TYPE> to create the 3D array.
#include <iostream>
#include <array>
#include <vector>
int main() {
std::array<std::array<int, 3>, 8> array_2d ;
std::vector<decltype(array_2d)> array_3d ;
int size = 4 ;
for(int i = 0; i < size; ++i)
{
for(int j = 0; j < 8; ++j)
for(int k = 0; k < 3; ++k)
array_2d[j][k] = j + k ;
array_3d.push_back(array_2d);
}
return 0;
}
Something like this you can use easily which does the job more easily without any manual memory management.
You can pass it to a function. The signature would be :
return_type function_name(const std::vector<std::array<std::array<int, 3>, 8>>& array_3d)
{ .... }
In
class M
{
public:
int i,j,k;
public:
int pass(int (*table)[8][3],int size);
}
you don't have to write public twice. You can simply put all of the public member data under the keyword public.
Also, you seem to be re-writing your function over again at the very end. Instead of
cout<<tables[i][j][k];
You can write
cout<<*tables