I want make any matrix[n][n+1] become an upper triangular matrix[n][n+1].
I did this code but that causes a segmentation fault.
void diagonalizarMatriz(float** Matriz, int n){
for(int i = 0; i < n-1; i++)
for(int k = 0; k < n; k ++)
for(int j = n; j >= i; j++)
Matriz[k][j] = Matriz[k][j] - ((Matriz[k][i] * Matriz[i][j]) / Matriz[i][i]);
}
int main(){
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [4];
//test matrix
Matriz[0][0] = 1;
Matriz[0][1] = 4;
Matriz[0][2] = 52;
Matriz[0][3] = 57;
Matriz[1][0] = -27;
Matriz[1][1] = -110;
Matriz[1][2] = -3;
Matriz[1][3] = -134;
Matriz[2][0] = 22;
Matriz[2][1] = 2;
Matriz[2][2] = 14;
Matriz[2][3] = 38;
diagonalizarMatriz(Matriz, 3);
Here
for(int j = n; j >= i; j++)
you start with n at the upper border of the dimensions of your array and the count up,
very soon you therefor access beyond your array, which gets you a segfault if you are lucky.
At a guess you want
for(int j = n; j >= i; j--)
to count down.
UPDATE
Assuming your question is about diagonalizing a matrix (as Eugene claims in the comment section):
In addition to what Yunnosch pointed out, diagonalizing a matrix means that the matrix must be a square n x n. However, in main you're initializing it to be a 3 x 4 matrix.
Original code
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [4];
To get rid of the segfault, change the following part in main (set matrix to 3 x 3):
float** Matriz = new float* [3];
for(int i = 0; i < 3 ; i++)
Matriz[i] = new float [3];
//test matrix
Matriz[0][0] = 1;
Matriz[0][1] = 4;
Matriz[0][2] = 52;
Matriz[1][0] = -27;
Matriz[1][1] = -110;
Matriz[1][2] = -3;
Matriz[2][0] = 22;
Matriz[2][1] = 2;
Matriz[2][2] = 14;
Finally, to get the following matrix (lower-triangular):
1 0 0
4 5 0
7 8 9
Remove the equal sign from your third nested loop:
for(int j = n; j > i; j--)
I assume from here you can work your way through this, to make it an upper-triangular matrix.
OLD ANSWER
Try this:
int matrix[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int row = 3;
int col = 3;
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
if (i > j) {
cout << "0" << " ";
} else
cout << matrix[i][j] << " ";
}
cout << endl;
}
Will give you this matrix
1 2 3
0 5 6
0 0 9
Related
I have an array a[10][50] and I created an array b[10][35] that stores the elements of a but I don't know how to create the array c[10][15] where the elements of array c are the elements left over from "a", can you help me?
int main(){
//Variables iniciales
float min = -32.768; //limite inferior
float max = 32.768; //limite superior
const int dim = 10; //dimension
const int N = 50; //poblacion inicial
//inicializar A
float a[dim][N];
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < N; j++)
{
float aleatorio;
aleatorio = (float)rand() / (float)RAND_MAX;
a[i][j] = min + abs(max - min) * aleatorio;
cout << i<<" - " << j << ":" << a[i][j] << endl;
}
}
//Dividir A en presas y depredadores
float preys_rate[] = { 0.7,0.9 };
float aleatorio = (float)0 + rand() % 1 / (float)RAND_MAX;
float rate = preys_rate[0] + (preys_rate[1] - preys_rate[0]) * aleatorio;
float N_h = round(N * rate); //Numero de presas
float N_p = N - N_h; //Numero de depredadores
//Asignar los miembros de A a H
float H[dim][35] ;
float fitness_value_h[35];
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < N_h; j++)
{
H[i][j] = a[i][j];
}
}
//Evaluar la funcion en el elemento N_h
for (int i = 0; i < N_h; i++)
{
fitness_value_h[i] = funcion_obj(H,35, 10 ,dim);
}
//Asignar los miembros restantes de A a P
float P[dim][15];
//float fitness_value_p[15];
//Si pertenecen a H[J], se ignoran
for (int i = 0; i < dim; i++)
{
for (int j = 35; j< N; j--)
{
if (H[i][j]=a[i][j])
{
}else{
P[i][j] = a[i][j];
}
}
}
}
As you can see, array a[10][50] has some random data, and array H[10][35] has the values of "a" and I need a third array (in this example, P) P[10][15] that has the other "a" elements
Why not create the new array and simply add the remaining elements at the end of whatever loop you're using? If you know exactly how long the arrays are supposed to be, you can do this very easily.
It would be much easier if you included code in your questions so that we could see where the issue is.
EDIT: You are doing the loop in a more complicated way than necessary. Never set the initial in in a for loop to be the number of repetitions and subtracting.
for (int j = 35; j < N; j--) //BAD
for (int j = 0; j <= 35; j++) //GOOD
To fix your issue, simply add a condition to your loop to do something past the 35th repitition.
//Asignar los miembros de A a H
float H[dim][35] ;
float fitness_value_h[35];
float K[dim][15] ;
float fitness_value_k[15];
for (int i = 0; i < dim; i++)
{
for (int j = 0; j < N_h; j++)
{
if (j < 35) {
H[i][j] = a[i][j];
}
else {
K[i][j] = a[i][j];
}
}
}
I'm trying to turn an ordered pair of numbers into a 3x3 matrix and am having troubles writing the conversion.
I've tried multiple variations of nested for loops to solve this issue, but I'm not getting the desired results.
This is my current attempt:
for(i = 0; i < 6; i++) {
row = matrixAin[i][0];
col = matrixAin[i][1];
for(j = 1; j <= row; j++) {
for(int k = 1; k <= col; k++) {
matrixA[j][k] = 1;
}
}
}
This is all the code I have:
#include <iostream>
using namespace std;
int main() {
int matrixAin[6][2]; // ordered pair of Matrix A
int matrixA[3][3]; // 3x3 matrix of Matrix A
int i, j, row, col; // for the for loops
// Sets Matrix A & B values to 0
for (i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
matrixA[i][j] = 0;
matrixB[i][j] = 0;
}
}
// input of Matrix A
cout << "Please input the ordered pairs for matrix A: ";
for (i = 0; i < 6; i++) {
cin >> matrixAin[i][0] >> matrixAin[i][1]; // row , col
}
// sets row / col to 1 for Matrix 3x3
// this is the code with the issue
for(i = 0; i < 6; i++) {
row = matrixAin[i][0];
col = matrixAin[i][1];
for(j = 1; j <= row; j++) {
for(int k = 1; k <= col; k++) {
matrixA[j-1][k] = 1;
}
}
}
// Displays matrix A
cout << "A= ";
for(int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << matrixA[i][j] << ' ';
}
cout << endl;
}
}
This is what the input for this matrix should look like
Please input the ordered pairs for matrix A:
1 2
1 3
2 1
2 2
3 2
3 3
This is the expected results:
A =
0 1 1
1 1 0
0 1 1
Your current code takes in each pair and then for each subrectangle of size row x col, sets the area of the rectangle to 1. It's really close. You just need to set once for each ordered pair:
for(i = 0; i < 6; i++) {
row = matrixAin[i][0];
col = matrixAin[i][1];
matrixA[row - 1][col - 1] = 1;
}
Replace the inner for-loop with matrixA[row - 1][col - 1] = 1;. Do not forget to check if col and row are between 1 and 3.
by now I have this code
int main() {
int cols;
cout << "cols";
cin >> cols;
int rows;
cout << "rows";
cin >> rows;
char** charArray = new char*[rows];
for (int i = 0; i < rows; ++i) {
charArray[i] = new char[cols];
}
// Fill the array
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
charArray[i][j] = char('1' + i + j );
}
}
// Output the array
for (int i = 0; i < rows; ++i) {
for (int j = i; j < cols ; ++j) {
cout << charArray[i][j];
}
cout << endl;
}
// Deallocate memory by deleting
for (int i = 0; i < rows; ++i) {
delete[] charArray[i];
}
and the output is like
1 2 3
2 3 4
How can I make it to be
1 2 3
4 5 6
I tried a lot, im a newbie in programming so can you please explain me what's the matter with this problem! Thanks a lot!!
Just change this:
charArray[i][j] = char('1' + i + j );
by:
charArray[i][j] = char('1' + i*cols + j);
BTW:
You have a typo in the output array loop:
for (int j = i; j < cols ; ++j) {
Should be:
for (int j = 0; j < cols ; ++j) {
Array filling loop should be
int count = 0;
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
charArray[i][j] = char('1' +count );
count++;
}
}
try with above code
You are building a matrix, here right. So it's 2-dimensional.
What the output means is that your matrix looks like:
1 2 3
2 3 4
Which is only natural, since, while filling it, you wrote for each element at coordinate i,j to be value 1+i+j. That means if i and j both equal 1 (second line, second column, since index start at 0), you put value the 1+1+1=3.
If you want to get the matrix:
1 2 3
4 5 6
You'll have to fill it with
charArray[i][j] = char('1' + i*ncols + j );
This way when you fill the first line, i = 0, so it's the same.
But then on the second line, i=1, so you get 1 + 3 + 0 = 4. And then 1+3+1=5, etc.
Edit: people are fast here. By the time I write my answer, already 2 others posted theirs :D
I have written a solution for the above problem but can someone please suggest an optimized way.
I have traversed through the array for count(2 to n) where count is finding subarrays of size count*count.
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] = {{1,2,3,4,5},{2,4,7,-2,1},{4,3,9,9,1},{5,2,6,8,0},{5,4,3,2,1}};
int max = 0;
int **tempStore, size;
for(int count = 2; count < n; count++)
{
for(int i = 0; i <= (n-count); i++)
{
for(int j = 0; j <= (n-count); j++)
{
int **temp = new int*[count];
for(int i = 0; i < count; ++i) {
temp[i] = new int[count];
}
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
temp[k][l] = a[i+k][j+l];
}
}
//printing fetched array
int sum = 0;
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
sum += temp[k][l];
cout<<temp[k][l]<<" ";
}cout<<endl;
}cout<<"Sum = "<<sum<<endl;
if(sum > max)
{
max = sum;
size = count;
tempStore = new int*[count];
for(int i = 0; i < count; ++i) {
tempStore[i] = new int[count];
}
//Locking the max sum array
for(int k = 0; k < count; k++)
{
for(int l = 0; l <count; l++)
{
tempStore[k][l] = temp[k][l];
}
}
}
//printing finished
cout<<"------------------\n";
//Clear temp memory
for(int i = 0; i < size; ++i) {
delete[] temp[i];
}
delete[] temp;
}
}
}
cout<<"Max sum is = "<<max<<endl;
for(int k = 0; k < size; k++)
{
for(int l = 0; l <size; l++)
{
cout<<tempStore[k][l]<<" ";
}cout<<endl;
}cout<<"-------------------------";
//Clear tempStore memory
for(int i = 0; i < size; ++i) {
delete[] tempStore[i];
}
delete[] tempStore;
Example:
1 2 3 4 5
2 4 7 -2 1
4 3 9 9 1
5 2 6 8 0
5 4 3 2 1
Output:
Max sum is = 71
2 4 7 -2
4 3 9 9
5 2 6 8
5 4 3 2
This is a problem best solved using Dynamic Programming (DP) or memoization.
Assuming n is significantly large, you will find that recalculating the sum of every possible combination of matrix will take too long, therefore if you could reuse previous calculations that would make everything much faster.
The idea is to start with the smaller matrices and calculate sum of the larger one reusing the precalculated value of the smaller ones.
long long *sub_solutions = new long long[n*n*m];
#define at(r,c,i) sub_solutions[((i)*n + (r))*n + (c)]
// Winner:
unsigned int w_row = 0, w_col = 0, w_size = 0;
// Fill first layer:
for ( int row = 0; row < n; row++) {
for (int col = 0; col < n; col++) {
at(r, c, 0) = data[r][c];
if (data[r][c] > data[w_row][w_col]) {
w_row = r;
w_col = c;
}
}
}
// Fill remaining layers.
for ( int size = 1; size < m; size++) {
for ( int row = 0; row < n-size; row++) {
for (int col = 0; col < n-size; col++) {
long long sum = data[row+size][col+size];
for (int i = 0; i < size; i++) {
sum += data[row+size][col+i];
sum += data[row+i][col+size];
}
sum += at(row, col, size-1); // Reuse previous solution.
at(row, col, size) = sum;
if (sum > at(w_row, w_col, w_size)) { // Could optimize this part if you only need the sum.
w_row = row;
w_col = col;
w_size = size;
}
}
}
}
// The largest sum is of the sub_matrix starting a w_row, w_col, and has dimensions w_size+1.
long long largest = at(w_row, w_col, w_size);
delete [] sub_solutions;
This algorithm has complexity: O(n*n*m*m) or more precisely: 0.5*n*(n-1)*m*(m-1). (Now I haven't tested this so please let me know if there are any bugs.)
Try this one (using naive approach, will be easier to get the idea):
#include <iostream>
#include<vector>
using namespace std;
int main( )
{
int n = 5; //Size of array, you may take a dynamic array as well
int a[5][5] =
{{2,1,8,9,0},{2,4,7,-2,1},{5,4,3,2,1},{3,4,9,9,2},{5,2,6,8,0}};
int sum, partsum;
int i, j, k, m;
sum = -999999; // presume minimum part sum
for (i = 0; i < n; i++) {
partsum = 0;
m = sizeof(a[i])/sizeof(int);
for (j = 0; j < m; j++) {
partsum += a[i][j];
}
if (partsum > sum) {
k = i;
sum = partsum;
}
}
// print subarray having largest sum
m = sizeof(a[k])/sizeof(int); // m needs to be recomputed
for (j = 0; j < m - 1; j++) {
cout << a[k][j] << ", ";
}
cout << a[k][m - 1] <<"\nmax part sum = " << sum << endl;
return 0;
}
With a cumulative sum, you may compute partial sum in constant time
std::vector<std::vector<int>>
compute_cumulative(const std::vector<std::vector<int>>& m)
{
std::vector<std::vector<int>> res(m.size() + 1, std::vector<int>(m.size() + 1));
for (std::size_t i = 0; i != m.size(); ++i) {
for (std::size_t j = 0; j != m.size(); ++j) {
res[i + 1][j + 1] = m[i][j] - res[i][j]
+ res[i + 1][j] + res[i][j + 1];
}
}
return res;
}
int compute_partial_sum(const std::vector<std::vector<int>>& cumulative, std::size_t i, std::size_t j, std::size_t size)
{
return cumulative[i][j] + cumulative[i + size][j + size]
- cumulative[i][j + size] - cumulative[i + size][j];
}
live example
This is my program in C++, which accepts an 2D array a[m][n]. If an element a[i][j] is zero, then set all the ith row and jth column elements to zero.
This is code sample:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
class SetZero{
public:
static void setZero(int **, int , int);
};
void SetZero::setZero(int ** a, int m, int n){
int i, j, k;
int ** b = new int *[m]; //flags to identify whether set to zero or not.
for(i = 0; i < m; i++){
b[i] = new int[n];
for(j = 0; j < n; j++)
b[i][j] = 1;
}
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
if(a[i][j] == 0 && b[i][j]){//DUMP here. If I change it to (a+i)[j], then works.
for (k = 0; k < n; k++){
a[i][k] = 0;//but there is NO dump here. Weird!
b[i][k] = 0;
}
for(k = 0; k < m; k++){
a[k][j] = 0;
b[k][j] = 0;
}
j = n;//break. next row loop.
}
for(int i = 0; i < m; i++)
delete[] b[i];
delete[] b;
}
int main(){
int a[4][5];
srand(time(NULL));
for(int i = 0; i < 4; i++){//create an 2D array
for(int j = 0; j < 5; j++){
a[i][j] = rand() % 100;
cout << a[i][j] << " ";
}
cout << endl;
}
SetZero::setZero((int **)a, 4, 5);//type cast.
cout << endl;
for(int i = 0; i < 4; i++){//print result
for(int j = 0; j < 5; j++)
cout << a[i][j] << " ";
cout << endl;
}
return 0;
}
Environment: WIN8 Visual Studio 2012.
Edit:
The program can compile but cannot execute normally. It will stop when it reaches if(a[i][j] == 0 && b[i][j]){
The error message is:
Unhandled exception at 0x012875DD in CCLC.exe: 0xC0000005: Access
violation reading location 0x0000004B.
SetZero::setZero((int **)a, 4, 5)
a is not an array of pointers, it is simply a 2 dimensional array.
notice how the access violation is reading address 0x0000004B? that's 75, a number between 0 and 99 :) because you are treating a 2 dimensional array (which is just a one dimensional array with a neat way of accessing it) as an array of arrays, it is taking one of the values in your array (75) to be the address of a sub array, then trying to read the non existent array at address 75 (or 0x0000004B)
I suggest that you 'flatten' your arrays and work with them as one dimensional arrays, which I find simpler:
void SetZero::setZero(int * a, int m, int n){
int i, j, k;
int * b = new int [m*n]; //flags to identify whether set to zero or not.
for(i = 0; i < m; i++){
b[i] = new int[n];
for(j = 0; j < n; j++)
b[i*n+j] = 1;
}
for(i = 0; i < m; i++)
for(j = 0; j < n; j++)
if(a[i*n+j] == 0 && b[i*n+j]){//DUMP here. If I change it to (a+i)[j], then works.
for (k = 0; k < n; k++){
a[i*n+k] = 0;//but there is NO dump here. Weird!
b[i*n+k] = 0;
}
for(k = 0; k < m; k++){
a[k*n+j] = 0;
b[k*n+j] = 0;
}
j = n;//break. next row loop.
}
delete[] b;
}
int main(){
int a[4*5];
srand(time(NULL));
for(int i = 0; i < 4; i++){//create an 2D array
for(int j = 0; j < 5; j++){
a[i*5+j] = rand() % 100;
cout << a[i*5+j] << " ";
}
cout << endl;
}
SetZero::setZero(a, 4, 5);//type cast.
cout << endl;
for(int i = 0; i < 4; i++){//print result
for(int j = 0; j < 5; j++)
cout << a[i*5+j] << " ";
cout << endl;
}
return 0;
}
One suggestion about the SetZero(). There is a function called memset() which allows you to set all bytes to a specific value given a starting pointer and the range. This function could make your SetZero() function more cleaner:
void * memset ( void * ptr, int value, size_t num );
Fill block of memory. Sets the first num bytes of the block of memory pointed by ptr to the specified value (interpreted as an unsigned char).
Parameters
ptr: Pointer to the block of memory to fill.
value: Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.
num: Number of bytes to be set to the value, size_t is an unsigned integral type.
For example, the following code block from your program:
for (k = 0; k < n; k++){
a[i][k] = 0;//but there is NO dump here. Weird!
b[i][k] = 0;
}
can be achieved by memset in a cleaner way:
memset(a[i], 0, n * sizeof(int));
memset(b[i], 0, n * sizeof(int));