How can I store a 1D array of 9 into a 2D array of 3x3? This is my current attempt:
for (j = 0; j < 3; j++)
{
if (i = 0)
{
a[i][j] = (int)data1[j];
}
if (i = 1)
{
a[i][j] = (int)data1[j + 3];
}
if (i = 2)
{
a[i][j] = (int)data1[j + 6];
}
}
}
something like this:
for (int i = 0; i < 9; i++)
{
a[i / 3][i % 3] = data[i];
}
And as ThisHandleNotInUse pointed out, MAYBE this one is more optimized depending on the circumstances and still scales to larger arrays with minor tweaking.
for (int i = 0; i < 9; i += 3)
{
for (int j = 0; j < 3; j++)
{
a[i][j] = data[i + j];
}
}
First of all. Logical equal sign must be written like this:if (i == 0)
This will check condition.
if (i=0)
Is not correct because you do assignement operator for i
You can try this:
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
if(i == 0)
{
a[i][j] = (int)data1[j];
}
if (i == 1)
{
a[i][j] = (int)data1[j+3];
}
if (i == 2)
{
a[i][j] = (int)data1[j+6];
}
}
}
If you are coding in c++, if(I=2) is incorrect it should be if (I==2) and I'm not sure why you need that
One possible solution is to have two nested for loops as you already have and this code: a[i][j]=data[j*3+i]. No if is needed then.
How optimized do you need this to be? What does your array contain? If your array contains structs, you're going to be copying them no matter what you do. If it contains references, you're going to be copying them (the references) no matter what you do.
If I were regularly converting an array[9] to an array[3,3], I'd just do this:
(arr = Old Array)
Array[,] NewArr = new Array[,]{ { arr[0], arr[1], arr[2] }, {arr[3], arr[4], arr[5]}, {arr[6], arr[7], arr[8]} };
EDIT: commenter below pointed out you were using a jagged array and not a multidimensional one in which case, in C#, the syntax would be:
Array[][] NewArr = new Array[][]{ new Array[]{ arr[0], arr[1], arr[2] }, new Array[]{ arr[3], arr[4], arr[5]}, new Array[]{ arr[6], arr[7], arr[8] } };
Related
What is the difference of multidimensional array initialization?
This is 'Longest Common Subsequence' problem.
string str1, str2;
getline(cin, str1);
getline(cin, str2);
int alphaCount[26] = { 0, };
int str1Len = str1.length();
int str2Len = str2.length();
int** arr = new int* [str1Len+1];
for (int i = 0; i < str1Len+1; i++)
{
arr[i] = new int[str2Len+1];
//Method One
for (int j = 0; j < str2Len+1; j++)
{
arr[i][j] = 0;
}
}
for (int i = 0; i < str1Len; i++)
{
for (int j = 0; j < str2Len; j++)
{
int y = i + 1;
int x = j + 1;
if (str1[i] == str2[j])
arr[y][x] = arr[y - 1][x - 1] + 1;
else
{
if (arr[y][x - 1] > arr[y - 1][x])// using uninitialized memory ERROR
arr[y][x] = arr[y][x - 1];
else
arr[y][x] = arr[y - 1][x];
}
}
}
cout << arr[str1.length()][str2.length()] << "\n";
// Method Two
// Not Error
for (int i = 0; i < str1Len + 1; i++)
{
for (int j = 0; j < str2Len + 1; j++)
{
arr[i][j] = 0;
}
}
// Method Three
//global valiable, Not Error
int arr[1001][1001];
Why Method One has error message
warning C6001: using uninitialized memory .
What is the difference between method 1 and method 2?
If there are more elements than numbers in the list, C++ pads the list with zeros. Thus this static array:
int alphaCount[26] = { 0, };
will have all its members initialized to zeroes (explicitly setting the first element to zero, and letting the others get automatically initialized).
This:
int** arr = new int* [str1Len+1];
for (int i = 0; i < str1Len+1; i++)
{
arr[i] = new int[str2Len+1];
for (int j = 0; j < str2Len+1; j++)
{
arr[i][j] = 0;
}
}
will also initialize all elements of the array to 0. However, in this case, the array is a 2D array, and is dynamically allocated (don't forget to free it afterwards). Typically you should check if new succeeded.
Note: Static array vs. dynamic array in C++.
The second method will initialize all the elements of the 2D array to zero, by using a double for loop.
The third method will initialize the global array's elements to zeroes, since Why are global and static variables initialized to their default values?
I think, I have just made a mistake: I was allocating a static 2D array and accessing it as 1 dimension.
Could you tell me how bad it is - method geta?
The code below works fine on my Windows, and Linux: actual is always eqauls to expected and stride is always equals to N.
#include "stdafx.h"
#define N 2000
int a[N][N];
int geta(int i, int j) {
return *(a[0] + i * N + j);
}
int main()
{
printf("Hello\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
a[i][j] = i + j;
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
int const expected = a[i][j];
int const actual = geta(i, j);
if (actual != expected) {
printf("wrong data at [%d,%d] expected=%d actual=%d", i, j, expected, actual);
}
}
}
for (int i = 1; i < N; i++) {
int stride = a[N] - a[N - 1];
if (stride != N) {
printf("wrong: i=%d c=%d N=%d", i, stride, N);
}
}
return 0;
}
Could you tell me how bad it is - method geta?
Bad. But correct. C++ guarantees memory for a to be contiguous and the memory layout to be row major, so your code returns in a correct manner the expected element. Let's see how:
The type of a[0] is int[2000] 1) . But as soon as you do arithmetic on it it decays, i.e. int*. So +i*N moves the pointer to the (beginning of the) line i and +j moves the pointer to the column j.
1) actually it's int(&)[2000] but not that relevant here
As a challange I don't use array indexes to assigning or searching. What I want to do is reading characters from a text file and put them in an array that is 15x15. I created a 2d array using indexes but I couldn't do the assigning without them. I tried two things but I couldn't come up with a working idea. My code is basically like that:
char **puzzleArray;
puzzleArray = new char*[15];
for (int i = 0; i < 15; i++)
puzzleArray[i] = new char[15];
char *c;
FILE* puzzle;
puzzle = fopen("puzzle.txt", "r");
for (int i=0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
fread(&c, sizeof(char), 1, puzzle);
if (*c != ' ' && *c != '\n')
strcpy(*(puzzleArray + (i * 15)) + j , c);
else
j--;
}
I also tried assignin like this:
char **puzzleArray;
puzzleArray = new char*[15];
for (int i = 0; i < 15; i++)
puzzleArray[i] = new char[15];
char c;
FILE* puzzle;
puzzle = fopen("puzzle.txt", "r");
for (int i=0; i < 15; i++) {
for (int j = 0; j < 15; j++) {
fread(&c, sizeof(char), 1, puzzle);
if (c != ' ' && c != '\n')
*(puzzleArray + (i * 15)) + j = c;
else
j--;
}
But none of them worked and when I do the second one compiler gives me the error "lvalue required as left operand of assignment".
Edit:
When I change the second code as:`
*(*(puzzleArray + (i * 15)) + j)
It compiled but when I tried to print the characters in array using this:
for (int i = 0; i < 15; i++) {
cout << endl;
for (int j = 0; j < 15; j++)
cout << *(*(puzzleArray + (i * 15)) + j);
}
//or using this
for (int i = 0; i < 15; i++) {
cout << endl;
for (int j = 0; j < 15; j++)
cout << puzzleArray[i][j];
}
It does not print characters and program crashes. In visual studio, it says an exception occurs at the assigning part.
You don't need nested allocations.
What's more, your code does not work because you assume your nested allocations will result in contiguous storage.
const int size = 15;
char* puzzleArray = new char[size*size];
// i'm not going to change file reading logic,
// but it should be done better
// ideally by one read to a buffer
// Also the style seems like a bad mix of C and C++,
// but I can't do much about it with only this little fragment of code.
FILE* puzzle = fopen("puzzle.txt", "r");
for (int i=0; i < size; i++) {
for (int j = 0; j < size; j++) {
char c;
fread(&c, 1, 1, puzzle);
if (c != ' ' && c != '\n')
puzzleArray[i*size + j] = c;
/*
// this does not seem right, i don't know what you're trying to do here
// i'm gonna assume that you want to move to the next line
else
j--;
*/
else
break;
}
}
There are two problems for your second try. And whether the memory is continous or not is not relevant. You can still use 2D array and using nested allocations.
(note that, although somebody downvoted my answer, but I think he/she did it wrong).
Here is the fully tested code using 2D array and nested memory allocations.
#include <iostream>
#include <cstdlib>
int main() {
using namespace std;
char **puzzleArray;
puzzleArray = new char*[15];
for (int i = 0; i < 15; i++)
puzzleArray[i] = new char[15];
char c;
FILE* puzzle;
puzzle = fopen("puzzle.txt", "r");
for (int i=0; i < 15; i++) {
for (int j = 0; j < 15; ) {
fread(&c, sizeof(char), 1, puzzle);
if (c != ' ' && c != '\n') {
*(*(puzzleArray + i) + j) = c; // you can see the difference if you compare with your original code.
++j;
}
}
}
for (int i = 0; i < 15; ++i) {
for (int j = 0; j < 15; ++j) {
cout << puzzleArray[i][j]; // you could use pointer arithmatic here too. using index is just convenient to show the result.
}
cout << std::endl;
}
}
So I have a program that I have created for finding an optimal binary search tree and it works great when the data set is around 100 but when I try and use a data set >1000 I get an access violation when weight[i][i] = frequency[i]; is called inside the computeOBST function. I'm not sure if that data set is to large or what. I'm stuck and not sure what else to try any help would be great.
int* keys = new int[numKeys];
int* keyLevel = new int[numKeys];
int* frequency = new int[numKeys];
int** weight = new int*[numKeys+2];
int** cost = new int*[numKeys];
int** root = new int*[numKeys];
void allocateArraySpace(int n){
int i;
// Allocate space for the 2-dim'l cost array
for (i = 0; i < numKeys + 2; i++) {
cost[i] = new int[numKeys + 2];
}
for (i = 0; i < numKeys + 1; i++) {
keyLevel[i] = numKeys + 1;
}
// Allocate space for the 2-dim'l root array
for (i = 0; i < numKeys + 1; i++) {
root[i] = new int[numKeys + 1];
}
//Allocate space for the 2-dim'l weight array
for (i = 0; i <= numKeys + 2; i++) {
weight[i] = new int[numKeys + 2];
}
}
void computeOBST(int n) {
numKeys = n;
int i, j, k, h, m;
allocateArraySpace(numKeys);
//creating weight matrix
for (int i = 1; i <= numKeys + 1; i++)
{
weight[i][i] = frequency[i];
for (j = i + 1; j <= numKeys; j++)
weight[i][j] = weight[i][j - 1] + frequency[j];
}
//
for (i = 1; i <= numKeys; i++)
for (j = i + 1; j <= numKeys + 1; j++)
cost[i][j] = INT_MAX;
//
for (i = 1; i <= numKeys + 1; i++)
cost[i][i - 1] = 0;
//
for (i = 1; i <= numKeys; i++) {
cost[i][i] = weight[i][i];
root[i][i] = i;
}
cost is only of size numKeys, but in your loop in allocateArraySpace you access numKeys+2 elements of it? There are similar issues for the other arrays.
Remember that arrays in C++ are 0-based, so if you do cost = new int *[numKeys], then cost[numKeys-1] is okay but cost[numKeys] and cost[numKeys+1] are out of bounds.
int* frequency = new int[numKeys]
then
for (int i = 1; i <= numKeys + 1; i++) { weight[i][i] = frequency[i]; ...
You will go out of bound. Undefined Behavior. It happens that this UB for small values does not result in a segmentation fault, while it does so for high values of numKeys.
This is just an example, you have the same error at many placrs. Check again all your loops and array bounds and set the correct limits.
In general, when you span an array of size numKeys, you scan it in the following way (remember C arrays are zero-based):
for (int i = 0; i < numKeys; i++) // first index is 0, last is numKeys-1
Following this nice example I found, I was trying to create a function that dynamically generates a 2D grid (two dimensional array) of int values.
It works fairly well the first couple of times you change the values but if crashes after that. I guess the part where memory is freed doesn't work as it should.
void testApp::generate2DGrid() {
int i, j = 0;
// Delete previous 2D array
// (happens when previous value for cols and rows is 0)
if((numRowsPrev != 0) && (numColumnsPrev != 0)) {
for (i = 0; i < numRowsPrev; i++) {
delete [ ] Arr2D[i];
}
}
// Create a 2D array
Arr2D = new int * [numColumns];
for (i = 0; i < numColumns; i++) {
Arr2D[i] = new int[numRows];
}
// Assign a random values
for (i=0; i<numRows; i++) {
for (j = 0; j < numColumns; j++) {
Arr2D[i][j] = ofRandom(0, 10);
}
}
// Update previous value with new one
numRowsPrev = numRows;
numColumnsPrev = numColumns;
}
I see 1 major bug:
// Assign a random values
for (i=0; i<numRows; i++){
for (j=0; j<numColumns; j++){
Arr2D[i][j] = ofRandom(0, 10);
}
}
Here the variable 'i' is used as the first index into 'Arr2D' and goes to a max of (numRows -1)
While in this code:
for (i=0; i<numColumns; i++)
{
Arr2D[i] = new int[numRows];
}
The variable 'i' is used as the first index but goes to a max of (numColumns-1). If numRows is much larger than numColumns then we are going to have a problem.
As a side note. When you try and clean up you are leaking the columns:
if((numRowsPrev != 0) && (numColumnsPrev != 0))
{
for (i=0; i<numRowsPrev; i++){
delete [ ] Arr2D[i];
}
// Need to add this line:
delete [] Arr2D;
}
Next thing to note.
This is truly not a good idea. Use some of the provided STL classes (or potentially boost Matrix). This looks like you are binding global variables and all sorts of other nasty stuff.
2-dim array in C++ with no memory issues:
#include <vector>
typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;
Usage:
TwoDArray Arr2D;
// Add rows
for (int i = 0; i < numRows; ++i) {
Arr2D.push_back(Array());
}
// Fill in test data
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
Arr2D[i].push_back(ofRandom(0, 10));
}
}
// Make sure the data is there
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
std::cout << Arr2D[i][j] << ' ';
}
std::cout << '\n';
}