I tried to solve the following problem:
Let x,y,z be integers in the domain [-5,5]. Display the number of solutions (x,y,z) that satisfy 3*x+y^3-z^2=0. My initial solution was this:
int main() {
int x=-6;
int y=-6;
int z=-6;
int p=0;
for(int i=-5; i<6; i++)
{
x++;
for (int j=-5; j<6; j++)
{
y++;
for(int k=-5; k<6; k++)
{
z++;
if(3*x +y*y*y -z*z==0)
p++;
}
}
}
std::cout<< p ;
return 0;
}
This is the correct solution:
int main() {
int x=-5;
int y=-5;
int z=-5;
int p=0;
for( x=-5; x<=5; x++)
for (y=-5; y<=5; y++)
for( z=-5; z<=5; z++)
if(3*x +y*y*y -z*z==0)
p++;
std::cout<< p;
return 0;
}
Why are these two different and what did I do wrong in the first one?
In the "correct" solution, y begins again from -5 for each new value of x. In your version, y carries on incrementing from its previous value, so the second iteration covers [5,15], the third [15,25], and so on.
The weird extra variable j covers the range you want y to cover each time, but y itself does not.
In the incorrect code, the variables y and z are not reset to the beginning of their range at the begining of the loop.
An even shorter correct exemple would be:
int main()
{
int p = 0;
for( int x=-5; x<=5; ++x )
for( int y=-5; y<=5; ++y )
for( z=-5; z<=5; ++z)
if( 3*x + y*y*y - z*z == 0 )
++p;
std::cout << p << std::endl;
return 0;
}
The variable initializations can be put directly into the loops.
As they are trivial variables there is no performance penalty.
Related
I am experimenting with vectors for the first time. So, to experiment, I created a class that constructs a 2d vector of integers and initializes them with numbers 0 through 9 in this order.
Here's the example I created:
#include <iostream>
#include <vector>
class VectorTest
{
private:
std::vector< std::vector<int> > m_v;
public:
VectorTest(int x, int y)
{
m_v.resize(y);
for (auto &element : m_v)
element.resize(x);
int count {0};
for (int i {0}; i < m_v.size(); ++i)
{
for (int j {0}; j < m_v[i].size(); ++j)
m_v[i][j] = count++ % 10;
}
}
}
void print()
{
for (int i {0}; i < m_v.size(); ++i)
{
for (int j {0}; j < m_v[i].size(); ++j)
{
std::cout << m_v[i][j];
}
std::cout << '\n';
}
}
void print(int x, int y)
{
std::cout << m_v[y][x];
}
};
int main()
{
VectorTest v(9, 9);
v.print();
std::cout << '\n';
v.print (6, 4);
return 0;
}
My question is: how can I modify this program to make m_v[x][y] instead of m_v[y][x] basically switch around the row and column indexes in the vector?
Considering that x is a row and y is a column, how can I make the inner vector store the columns and the outside vector store the rows? Because right now I have to access the coords as m_v[y][x] but I wanted this to be accessed as m_v[x][y].
Why don't just swap places "x" and "y" in constructor? Nothing else is needed.
Or I misunderstood the problem?
VectorTest(int x, int y)
{
m_v.resize(x /* was "y" */);
for (auto &element : m_v)
element.resize(y /* was "x" */);
int count {0};
for (int i {0}; i < m_v.size(); ++i)
{
for (int j {0}; j < m_v[i].size(); ++j)
m_v[i][j] = count++ % 10;
}
}
}
I am working on a C++ class that consists of a 2D Vector of Doubles. I am about to create the 2D Vector but when I try to edit the values inside of it, the program crashes. I have tried using the [][] operator and setting it equal to myDub and I have tried using a class like myMat.editSlot(i,j,myDub) and both have caused the program to crash.
//n == # of rows and cols (all matrices are square)
//infile opens the file properly
mat my_mat(n,n);
// Read input data
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
double myDub;
inFile >> myDub;
my_mat.editSlot(i,j,myDub);
}
}
and here is the class:
class mat
{
mat( int x , int y ) {
int row = x;
int col = y;
vector<vector<double>> A( row , vector<double>( row , 0 ) );
for ( int i = 0; i<row; i++ )
{
for ( int j = 0; j<col; j++ )
{
cout << setw( 6 ) << A[i][j];
}
cout << endl;
}
}
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
vector<vector<double>> A;
private:
int n;
};
It looks to me that the way you're initializing A is wrong. Try something like this:
A = vector<vector<double>>( row , vector<double>( row , 0 ) );
Another thing to consider both the constructor and the edit function aren't declared public.
Main problem that leads to crush is that you change size of a temporal vector A in your constructor while A vector that you declared as a field in your class object is not touched.
I suggest doing something like this:
mat(int x,int y) : A(y,vector<double>(x,0)) {
int row = x;
int col = y;
for(int i=0; i<row; i++)
{
for(int j=0; j<col; j++)
{
cout<<setw(6)<<A[i][j];
}
cout<<endl;
}
}
}
In this case you won't hide your A field in class with temporal A object in constructor function.
Also please pay attention not to swap x and y in your functions. For example, you have an error in your editSlot function:
void editSlot( int x , int y , double val ) {
A[x][y] = val;
}
, it should be:
A[y][x] = val;
according to constructor.
I am working on C++ printing vectors in grid.
Here, I need to put random numbers in a vector size of 3x * 3y. And then I have to print them out with two dimensional matrix with one array.
I do not understand how to represent two dimensional matrix with one array.
In addition, I am not sure how to print out multidimensional vectors. I have to work on print_vector function which prints vectors with grid form.
Could you please help me to improve this code below?
int main()
{
populate_vector();
return 0;
}
void populate_vector()
{
int x,y;
cout<<"Enter two Vectors x and y \n->";
cin>> x;
cin>> y;
srand((unsigned)time(NULL));
std::vector<int> xVector((3*x) * (3*y));
for(int i = 0; (i == 3*x && i == 3*y); ++i){
xVector[i] = rand() % 255 + 1;
if(i == 3*x){
cout << "\n";
}
}
print_vector(xVector);
}
void print_vector(vector<int> &x) {
}
I'm not an expert, but I like to just have a vector of vectors.. something like:
void print_vector(vector<vector<int>>& m_vec)
{
for(auto itY: m_vec)
{
for(auto itX: itY)
cout << itX << " ";
cout << endl;
}
}
void populate_vector()
{
int x,y;
cout << "Enter Two Vectors x and y \n ->";
cin >> x;
cin >> y;
srand((unsigned)time(NULL));
vector<vector <int>> yVector;
for(auto i = 0; i < y*3; ++i)
{
vector<int> xVector;
for(auto j = 0; j < x*3; ++j)
xVector.push_back(rand()%255+1);
yVector.push_back(xVector);
}
print_vector(yVector);
}
EDIT: Ooh, I'd never seen this site before, thanks Saykou... here is the code working: http://cpp.sh/3vzg
Something like this will clarify your code, there is a procedure where the vector is populated, and another one where the vector is printed
int main()
{
int x,y;
std::cout<<"Enter two Vectors x and y \n->";
std::cin>> x;
std::cin>> y;
srand((unsigned)time(NULL));
int xSize = x * 3; // it is important to have the size of the final grid stored
int ySize = y * 3; // for code clarity
std::vector<int> xVector( xSize * ySize);
// iterate all y
for ( y = 0 ; y < ySize; ++y) {
// iterate all x
for ( x = 0 ; x < xSize; ++x) {
// using row major order https://en.wikipedia.org/wiki/Row-_and_column-major_order
xVector[y * xSize + x] = rand() % 255 + 1;
}
}
// when printing you want to run y first
for ( y = 0 ; y < ySize; ++y) {
for ( x = 0 ; x < xSize; ++x) {
// iterate all y
printf("%d ", xVector[y * xSize + x] );
}
printf("\n");
}
}
I think you want to pay attention to this step, where you can convert x and y position into a one array dimension. It's simple you just have to multiply the y by the size of x and add x.
So something like this in two dimensions
1 2 3
4 5 6
will end up in something like this
1 2 3 4 5 6
you can see it running here
#include <iostream>
using namespace std;
int main()
{
int x = 0;
for int (i=0; i<100; i++)
if (i%9 == 0) x = i;
else x = -1;
cout << x;
return 0;
}
This snippet of code returns the value 99.
When i read it line by line I understand it like this.
Declare a variable x, assign it the value 0.
For i = 0, i is less than 100, increment i by 1.
if the remainder of i/9 is equal to 0, assign the value of i to x.
If it isn't set x to be equal to -1
Print out x
In the first step of the for loop i is assigned the value 0. 0 divided by 9 is equal to 0 which mets the conditions of the if statement so why would it not print out that x is equal to 0 instead of 99?
Line By Line
1) Declare a variable x; assign it the value 0.
#include <iostream>
int main()
{
int x=0;
}
2) For i = 0, i is less than 100, increment i by 1.
#include <iostream>
int main()
{
int x=0;
for(int i=0; i<100; i++) {};
}
3) If the remainder of i/9 is equal to 0, assign the value of i to x.
#include <iostream>
int main()
{
int x=0;
for(int i=0; i<100; i++)
{
if(i%9==0)
{
x = i;
}
};
}
4) If it isn't set, x should equal -1:
#include <iostream>
int main()
{
int x=0;
for(int i=0; i<100; i++)
{
if(i%9==0)
{
x = i;
}
else
{
x = -1;
}
};
}
5) Print out x
#include <iostream>
int main()
{
int x=0;
for(int i=0; i<100; i++)
{
if(i%9==0)
{
x = i;
}
else
{
x = -1;
}
};
std::cout << x << std::endl;
}
DEMO of last one.
References to more C++ fun activities
worldbestlearn
WikiBooks
course
The output is correct. Each time through the loop, x gets either the value of i or the value -1. The last time through the loop, i == 99 and i % 9 is indeed 0, so x gets assigned the value 99. Then i gets the value 100, the loop exits, and the rest of the program prints the current value of x, which is 99.
Note that the if/else is the body of the for loop. The loop doesn't exit just because i%9 is 0 in the if.
Only the single statement after the for loop is inside the for loop. Note that if ... else ... is one statement (that contains other statements).
The exact same code should be better written as:
int main()
{
int x = 0;
for (int i=0; i<100; i++)
{
if (i%9 == 0)
x = i;
else
x = -1;
}
cout << x;
return 0;
}
and now it should be easy to see why nothing is printed until the loop ends.
I've looked up some websites but I couldn't find an answer to my problem.
Here's my code:
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 6;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
printing(Array);
}
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{
int c, tmp, x;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into Array[][]
for (int e = 0; e<AS; e++)
{
for (int d = 0; d<AS; d++)
{
Brray[dice] = Array[e][d];
dice++;
}
}
***There's a part missing here***
}
What I have to do is, write a program using 3 functions.
The 1st function would fill my 2D array randomly (no problem with this part)
the 2nd function would print the unsorted array on the screen (no problem with this part)
and the 3rd function would sort my array diagonally as shown in this picture:
Then I need to call the 2nd function to print the sorted array. My problem is with the 3rd function I turned my 2D array into a 1D array and sorted it using Bubble sorting, but what I can't do is turn it back into a 2D array diagonaly sorted.
If you can convert from a 2D array to a 1D array, then converting back is the reverse process. Take the same loop and change around the assignment.
However in your case the conversion itself is wrong. It should take indexes in the order (0;0), (0;1), (1;0). But what it does is take indexes in the order (0;0), (0;1), (1;1).
My suggestion is to use the fact that the sum of the X and Y coordinates on each diagonal is the same and it goes from 0 to AS*2-2.
Then with another loop you can check for all possible valid x/y combinations. Something like this:
for ( int sum = 0; sum < AS*2-1; sum++ )
{
for ( int y = sum >= AS ? sum-AS+1 : 0; y < AS; y++ )
{
x = sum - y;
// Here assign either from Array to Brray or from Brray to Array
}
}
P.S. If you want to be really clever, I'm pretty sure that you can make a mathematical (non-iterative) function that converts from the index in Brray to an index-pair in Array, and vice-versa. Then you can apply the bubble-sort in place. But that's a bit more tricky than I'm willing to figure out right now. You might get extra credit for that though.
P.P.S. Realization next morning: you can use this approach to implement the bubble sort directly in the 2D array. No need for copying. Think of it this way: If you know a pair of (x;y) coordinates, you can easily figure out the next (x;y) coordinate on the list. So you can move forwards through the array from any point. That is all the the bubble sort needs anyway.
Suppose you have a 0-based 1-dimensional array A of n = m^2 elements. I'm going to tell you how to get an index into A, given and a pair of indices into a 2D array, according to your diagonalization method. I'll call i the (0-based) index in A, and x and y the (0-based) indices in the 2D array.
First, let's suppose we know x and y. All of the entries in the diagonal containing (x,y) have the same sum of their coordinates. Let sum = x + y. Before you got to the diagonal containing this entry, you iterated through sum earlier diagonals (check that this is right, due to zero-based indexing). The diagonal having sum k has a total of k + 1 entries. So, before getting to this diagonal, you iterated through 1 + 2 + ... + (sum - 1) entries. There is a formula for a sum of the form 1 + 2 + ... + N, namely N * (N + 1) / 2. So, before getting to this diagonal, you iterated through (sum - 1) * sum / 2 entries.
Now, before getting to the entry at (x,y), you went through a few entries in this very diagonal, didn't you? How many? Why, it's exactly y! You start at the top entry and go down one at a time. So, the entry at (x,y) is the ((sum - 1) * sum / 2 + y + 1)th entry, but the array is zero-based too, so we need to subtract one. So, we get the formula:
i = (sum - 1) * sum / 2 + y = (x + y - 1) * (x + y) / 2 + y
To go backward, we want to start with i, and figure out the (x,y) pair in the 2D array where the element A[i] goes. Because we are solving for two variables (x and y) starting with one (just i) and a constraint, it is trickier to write down a closed formula. In fact I'm not convinced that a closed form is possible, and certainly not without some floors, etc. I began trying to find one and gave up! Good luck!
It's probably correct and easier to just generate the (x,y) pairs iteratively as you increment i, keeping in mind that the sums of coordinate pairs are constant within one of your diagonals.
Store the "diagonally sorted" numbers into an array and use this to display your sorted array. For ease, assume 0-based indexing:
char order[] = { 0, 1, 3, 6, 10, 2, 4, 7, 11, 15, .. (etc)
Then loop over this array and display as
printf ("%d", Array[order[x]]);
Note that it is easier if your sorted Array is still one-dimensional at this step. You'd add the second dimension only when printing.
Following may help you:
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <vector>
template<typename T>
class DiagArray
{
public:
DiagArray(int size) : width(size), data(size * size), orders(size * size)
{
buildTableOrder(size);
}
const T& operator() (int x, int y) const { return data[orders[width * y + x]]; }
T& operator() (int x, int y) { return data[orders[width * y + x]]; }
void sort() { std::sort(data.begin(), data.end()); }
void display() const {
int counter = 0;
for (auto index : orders) {
std::cout << std::setw(5) << data[index];
counter++;
if (counter % width == 0) {
std::cout << std::endl;
}
}
}
private:
void buildTableOrder(int size)
{
int diag = 0;
int x = 0;
int y = 0;
for (int i = 0; i != size * size; ++i) {
orders[y * size + x] = i;
++y;
--x;
if (x < 0 || y >= size) {
++diag;
x = std::min(diag, size - 1);
y = diag - x;
}
}
}
private:
int width;
std::vector<T> data;
std::vector<int> orders;
};
int main(int argc, char *argv[])
{
const int size = 5;
DiagArray<int> da(size);
for (int y = 0; y != size; ++y) {
for (int x = 0; x != size; ++x) {
da(x, y) = size * y + x;
}
}
da.display();
std::cout << std::endl;
da.sort();
da.display();
return 0;
}
Thank you for your assistance everyone, what you said was very useful to me. I actually was able to think about clearly and came up with a way to start filling the array based on your recommendation, but one problem now, Im pretty sure that my logic is 99% right but there's a flaw somewhere. After I run my code the 2nd array isnt printed on the screen. Any help with this?
#include "stdafx.h"
#include <iostream>
#include <math.h>
#include <time.h>
#include<iomanip>
#include<array>
#include <algorithm>
using namespace std;
const int AS = 5;
int filling(void);
void printing(int[AS][AS]);
int forsorting(int[][AS], int);
int main()
{
int funny = 0;
int timpa = 0;
int counter = 0;
int Array[AS][AS];
srand(time(0));
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
Array[i][j] = filling();
}
cout << "The unsorted array is" << endl << endl;
printing(Array);
cout << "The sorted array is" << endl << endl;
for (int il = 0; il<AS; il++)
{
for (int elle = 0; elle<AS; elle++)
Array[il][elle] =forsorting(Array, funny);
}
printing(Array);
system("PAUSE");
return 0;
}
int filling(void)
{
int kira;
kira = rand() % 87 + 12;
return kira;
}
void printing(int Array[AS][AS])
{
int counter = 0;
for (int i = 0; i<AS; i++)
{
for (int j = 0; j<AS; j++)
{
cout << setw(5) << Array[i][j];
counter++;
if (counter%AS == 0)
cout << endl << endl;
}
}
}
int forsorting(int Array[AS][AS], int funny)
{int n;
int real;
int dice = 0;
int Brray[AS*AS];
int timpa = 0;
int super = 0;
int median;
int row=0;
int col=AS-1;
//Transofrming Array[][] into Brray[]
for (int i = 0; i < AS; i++)
{
for (int k = 0; k < AS; k++)
{
Brray[timpa] = Array[i][k];
timpa++;
}
}
//Bubble sorting in Brray[]
for (int passer = 1; passer <= AS-1; passer++)
{
for (int timon = 1; timon <= AS-1; timon++)
{
if (Brray[timpa]>Brray[timpa + 1])
{
super = Brray[timpa];
Brray[timpa] = Brray[timpa + 1];
Brray[timpa + 1] = super;
}
}
}
//Transforming Brray[] into sorted Array[][]
for(int e=4;e>=0;e--)//e is the index of the diagonal we're working in
{
if(AS%2==0)
{median=0.5*(Brray[AS*AS/2]+Brray[AS*AS/2-1]);
//We start filling at median - Brray[AS*AS/2-1]
while(row<5 && col>=0)
{real=median-Brray[AS*AS/2-1];
Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
else {
median=Brray[AS*AS/2];
//We start filling at Brray[AS*AS/2-AS/2]
while(row<5 && col>=0)
{real=Brray[AS*AS/2-AS/2];
n=Array[row][col]=Brray[real];
real++;
col--;
row++;}
}
}
return n;
}
Thanks again for your assistance