Two dimensional array 4x4, product of diagonals? - c++

I'm trying to take the product of all of the diagonal numbers in a 4x4 array. I know how to grab the numbers and print them, but I'm not sure how to take the product of them, how would I make it calculate the product of the 8 numbers?
#include <iostream>
using namespace std;
for (int row = 0; row < 4; row++)
{
for (int column = 0; column < 4; column++)
{
if (row==column || row == 3 - column)
{
double product = 1;
product *= arr[row][column]
cout << product << ".";
}
}
}

Note:
There are only 7 diagonal elements. You are counting the element in the centre of the matrix twice.
you don't need to iterate the whole array in order to know about the diagonals. The diagonals have a nice property of row == column as you have observed and you only need to iterate along the diagonals.
To make things clearer and easier, calculate the two diagonal products separately:
double product = 1;
for (int row = 0; row < 4; row++) {
product *= arr[row][row]
}
for (int row = 0; row < 4; row++) {
product *= arr[row][4 - (row + 1)]
}
If you consider both entries in each row at a time, you'll have to also account for the fact that the middle element appears in both diagonals which makes the code unnecessarily messy.

why you are defining the variable product inside the loop,thats why the previous data stored in the variable is lost when it goes out of scope.
#include <iostream>
using namespace std;
double product = 1; // var product should be defined out of the loop
for (int row = 0; row < 4; row++)
{
for (int column = 0; column < 4; column++)
{
if (row==column || row == 3 - column)
{
product *= arr[row][column];
}
}
}
cout << product << ".";

Related

How can I delete specific rows and columns in a given matrix for C++?

I have a multidimensional vector of chars, and I want to be able to delete a specific column or row on command. For example, if I had this matrix:
A B C D
L K T M
A M T N
Deleting the second column would change the matrix to
A C D
L T M
A T N
Then, deleting the third row would change the matrix to
ACD
LTM
My code that I have written for this purpose currently returns an error for both row and column deletions:
void verticalSearch(vector< vector<char> >matrix, int startIndex, int lengthWord, string word)
{
for(int k = 0; k < matrix[0].size() ; k++) // iterating for each column
{
for (int i = 0; i < matrix.size() - lengthWord + 1; i++) // for each row
{
char c;
string s = "";
for (int j = startIndex; j < startIndex + lengthWord; j++) // this startIndex is always 0
{ // but this for loop stands for iterating in a length of given word
c = matrix[i + j][k]; // adding given index of matrix to character c
s += c;
}
if (s == word) // if a specific word is founded
{
matrix[0].erase(matrix[0].begin() + k); // delete this column but not working correctly
cout << "Word is founded" << endl;
printMatrix(matrix); // And print it
}
}
}
}
Can somebody please tell me what's wrong?
You have a vector of rows, therefore to delete a column you must delete one character from each row. You can write a loop to do this. E.g.
for (int row = 0; row < matrix.size(); ++row)
matrix[row].erase(matrix[row].begin() + k);
EDIT
So your code should end up looking like this
if (s == word) // if a specific word is founded
{
// delete a column
for (int row = 0; row < matrix.size(); ++row)
matrix[row].erase(matrix[row].begin() + k);
cout << "Word is founded" << endl;
printMatrix(matrix); // And print it
}

Example of CLI/C++ dataGridView - setting index of comobox cell list

I am trying to set up a dataGridView in MS CLI/C++.
Simply if I have a list of letters (Say A - D) I want to populate the dataGridView type. what I want to do is to create a for loop that will populate each cell with a Letter
like Row(0) Cell(0) with A, Row(0) Cell(1) with B, etc
I can't find a simple direct way to do it. can Someone help please
A sample of my code is below
int columns = getColumnCount();
int rows = getRowCount();
// Clear existing items
dataGridView1->Columns->Clear();
dataGridView1->Rows->Clear();
DataGridViewComboBoxColumn ^ dataGridComboColumn = gcnew DataGridViewComboBoxColumn;
DataGridViewCell ^ dataGridComboCell = gcnew DataGridViewComboBoxCell;
DataGridViewComboBoxColumn ^ dataGridComboColumn = gcnew DataGridViewComboBoxColumn;
for (int col = 0; col < columns; col++)
{
//addItemToComboBox(dataGridComboColumn);
dataGridComboColumn->Items->Add("A");
dataGridComboColumn->Items->Add("B");
dataGridComboColumn->Items->Add("C");
dataGridComboColumn->Items->Add("D");
dataGridView1->Columns->Add(dataGridComboColumn);
}
for (int row = 0; row < rows; row++)
{
dataGridView1->Rows->Add(row);
}
dataGridView1->Rows[1]->Cells[1]->Value = dataGridComboColumn->Items[1];
int selectcnt = 0;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
selectcnt++;
}
}
}
I found a solution to my implementation.
I have to define a temporary cell
DataGridViewComboBoxCell^ tempCell = (DataGridViewComboBoxCell^)dataGridView1->Rows[row]->Cells[col];
if (tempCell != nullptr)
{
dataGridView1->Rows[row]->Cells[col]->Value = tempCell->Items[selectCnt];
}
and just cycle through the list
This did the trick

C++ Filling partially filled 2D array with Average

I'm trying to experiment with 2D arrays in C++ and I'm working on a project that makes a 4x4 2D array that holds a number of student grades but it is partially filled via a text file. Only 3 out of the 4 columns are filled. I want to filled the last column with an average of the grades in the previous rows of each column.
The problem is I can't figure out exactly how to fill the last column.
This my code for calculating the average.
const int SIZE = 4;
const int ROWS = 4;
const int COLS = 4;
int total = 0;
for (int i = 0; i < ROWS; i++)
{
total = 0;
for (int j = 0; j < COLS - 1; j++)
{
total += studentGrades[i][j];
average = total / (COLS - 1);
studentGrades[0][3] = average;
studentGrades[1][3] = average;
studentGrades[2][3] = average;
studentGrades[3][3] = average;
}
}
It seems like I'm close because I'm getting good results but the last column isn't displaying the right values and I feel like there's a more efficient way to fill the last column instead of manually inserting into each index.
You are assigning the last computed average to all rows every time. This means at the end you will have the average of row 4 in all 4 columns. Also consider changing your variables (studentGrades and total) to a floating point type for more accuracy.
const int SIZE = 4;
const int ROWS = 4;
const int COLS = 4;
for (int i = 0; i < ROWS; i++)
{
int total = 0;
for (int j = 0; j < COLS - 1; j++)
total += studentGrades[i][j];
studentGrades[i][COLS - 1] = total / (COLS - 1);
}
You could also make use of the standard library:
#include <numeric>
// ...
constexpr int Rows = 4, Cols = 4, NGrades = Cols - 1;
for (int i = 0; i < Rows; i++)
studentGrades[i][NGrades] = std::accumulate(studentGrades[i], studentGrades[i] + NGrades, 0) / NGrades;
As in my first solution, consider using floating point types. To enable float arithmetic change the 0 of std::accumulate to 0.0 or 0.0f.
Here is an explanation of std::accumulate.
The logic is wrong. You can only calculate the average and fill the last column after you have totaled the other columns, and you can only fill one row at a time, instead of trying to do all four rows together. This is the correct loop
for (int i = 0; i < ROWS; i++)
{
total = 0;
for (int j = 0; j < COLS - 1; j++)
{
total += studentGrades[i][j];
}
average = total / (COLS - 1);
studentGrades[i][3] = average;
}
It's just a matter of doing things in the right order and at the right time.
Plus you should pay attention to the integer division problem that Yksisarvinen pointed out.

How to create the editable field's according to their number (is inputted from the keyboard)?

We have decided to create a matrix calculator. It is needed to create fields for double numbers, which are also inputted from the keyboard. We are working in Embarcadero® C++Builder 10.2. The program must be written with C++ only.
An example of what I mean:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
// Delete previous boxes, if any
for (size_t Col = 0; Col < FEdits.size(); Col++)
{
for (size_t Row = 0; Row < FEdits[Col].size(); Row++)
{
delete FEdits[Col][Row];
}
}
FEdits.clear();
// Generate new boxes
int Cols = StrToInt(ColsEdit->Text);
int Rows = StrToInt(RowsEdit->Text);
FEdits.resize(Cols);
for (int Col = 0; Col < Cols; Col++)
{
for (int Row = 0; Row < Rows; Row++)
{
TEdit * Edit = new TEdit(this);
Edit->Parent = this;
Edit->Top = 24 + Row * 32;
Edit->Left = 200 + Col * 64;
Edit->Width = 48;
FEdits[Col].push_back(Edit);
}
}
}
You can then use FEdits[Col][Row] to access individual edit boxes. FEdits should be defined as a form field as:
std::vector<std::vector<TEdit *> > FEdits;
You need to include "vector" at the top of your unit:
#include <vector>

array questions (homework)

I am stuck on the last few problems of an array exercise. Could anyone lend a hand?
Write C++ statements that do the following:
store 5 in the first column of an array and make sure that the value in each subsequent column is twice the value in the previous column.
print the array one row per line.
print the array one column per line.
I think this will work for question #2:
for (row = 0; row < 10; row++)
{
for (col = 0; col < 20; col++)
cout << alpha[row][col] << " ";
cout << endl;
}
but question 1 and 3 have me stumped. thanks
Here's what i came up with after your tips. thanks everyone
3.
for (col = 0; col < 20; ++col)
{
for (row = 0; row < 20; ++row)
cout << alpha[row][col] << " ";
cout << endl;
}
1.
for (row = 0; row < 10; row++)
alpha[row][0] = 5;
for (col = 1; col < 20; col++)
for (row = 0; row < 10; row++)
alpha[row][col]=alpha[row][col-1]*2;
For #1, run a loop that starts at zero and goes until the number of rows. In each iteration just assign 5 to array[row][0]=5 (since coloumn 0 is the first coloumn).
Now run a loop from 1 to the number of coloumns. Inside, run another loop for each row. just assign array[row][col]=array[row][col-1]*2.
For #3, simply reverse the order of the loops. We iterate over all coloumns, and for each coloumns we have to iterate over all rows and print a newline after that.
I would post code, but it is better for you to try to understand and write the code yourself.
for each row, insert 5 into the first column (index 0), then in a loop, iterate from 1 through the number required, and the value at the current column index = 2 * value at previous column index (i.e. col - 1).
re-arrange the row, col loops.
Well for 1, just take the previous col and multiple by 5. So when your going through a loop, it'd be like col[position your at now] = col[prev pos]*2
For question #3, just reverse the order of loops, as
for (col = 0; col < 20; col++)
{
for (row = 0; row < 10; row++)
cout << alpha[row][col] << " ";
cout << endl;
}
Isn't it simple?
For question #1, just use the same reverse order of loops, and do this
int value = 5;
for (col = 0; col < 20; col++)
{
for (row = 0; row < 10; row++)
alpha[row][col] = value;
value = 2 * value;
}