Calculating sum in 2d array for each row - c++

i'm very new to C++ and im trying to do some exercise about data handling and 2d array
so my problem is I seems to get weird results when im trying to run this code that i write to calculate the sum of 1st row in 2d array and the datafile that i use should look like this
1 19 93 92 87
1 20 76 87 75
1 19 75 87 80
1 22 86 23 30
1 20 89 82 29
1 21 28 39 31
1 22 39 21 49
1 20 40 39 19
1 20 22 11 22
1 19 75 90 15
this is the code that i use
void sumRow(){
int data [10][5];
float sum;
ifstream f("datafile.txt");
for(int row = 0; row < 10; row++){
for(int column = 0; column < 5; column++){
f >> data[row][column];
}
}
for (int column = 2; column < 5;column++){
sum+= data[1][column];
}
cout << sum;
}

Shouldn't your first row index be 0 instead of 1 and if you want sum of all the elements of first row then why start the for loop with column = 2 rather than column = 0.

The index of the first row (and column) on arrays in c++ is 0, so if you want to calculate the sum of the items on the first row you should do:
for (int column = 0; column < 5; column++){
sum += data[0][column];
}

Related

Sorting the first column of a 2D Array in alphabetical order without the sort function [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 2 days ago.
Improve this question
I need to sort the first column of my 2D array into alphabetical order. I am not allowed to use the algorithm library so I cannot use the sort function... additionally, I need to move the rest of the row along with the words being sorted.
I tried iterating through the first column of my matrix and comparing one element to its proceeding element and swapping the two values via temp variable. When I do this, it messes up the 2d array entirely.
void sortTable(){
string temp;
for(int i = 0; i < noRows; i++){
for(int j = i+1; j < noRows; j++){
if(myTable[i][0] < myTable[j][0]){
temp = myTable[i][0];
myTable[i][0] = myTable[j][0];
myTable[j][0] = temp;
}
}
}
}
this is the table:
Dave Philadelphia M 39 72 167.6
Carl Izmir M 32 70 155.9
Alex Singapore M 41 74 170.5
Bert Zhongshan M 42 68 166.8
Luke Porto Alegre M 34 72 163.6
Myra Karaj F 23 62 98.8
Elly Vienna F 30 66 124.9
Jake Ulsan M 32 69 143.5
Fran Hamburg F 33 66 115.5
Omar Kampala M 38 70 145.4
Page Tehran F 31 67 135.2
Quin Chennai M 29 71 176.0
Hank Shanghai M 30 71 158.7
Ivan London M 53 72 175.9
Kate Patna F 47 69 139.3
Neil Daejeon M 36 75 160.9
Ruth Managua F 28 65 131.8
Gwen Bucharest F 26 64 121.1
which needs to end up as...
Alex Singapore M 41 74 170.5
Bert Zhongshan M 42 68 166.8
Carl Izmir M 32 70 155.9
Dave Philadelphia M 39 72 167.6
Elly Vienna F 30 66 124.9
Fran Hamburg F 33 66 115.5
Gwen Bucharest F 26 64 121.1
Hank Shanghai M 30 71 158.7
Ivan London M 53 72 175.9
Jake Ulsan M 32 69 143.5
etc..
As indicated in my comments, you can sort the array without sorting the array. The trick is to use an index array, and instead the index array is sorted.
Something similar to this:
std::vector<int> idx;
//...
void sortTable(int noRows)
{
idx.resize(noRows);
// Initialize the index array
for (int i = 0; i < noRows; ++i)
idx[i] = i;
// Sort using the index array
for(int i = 0; i < noRows; i++)
{
for(int j = i+1; j < noRows; j++)
{
// Note that we use the index array idx, and not simply i and j
if(myTable[idx[i]][0] > myTable[idx[j]][0])
{
// Note we are swapping the index, and not the rows themselves
int temp = idx[i];
idx[i] = idx[j];
idx[j] = temp;
}
}
}
Then when it comes time to display the results:
for (int i = 0; i < nRows; ++i)
{
for (int j = 0; j < 5; ++j)
std::cout << myTable[idx[i]][j] << " ";
std::cout << "\n";
}
Live Example
If you can't use std::vector, then create an array that has enough elements, and initialize the array with elements 0, 1, 2, etc. up to nRows-1.

How do can I get rid of the blank lines that are created c++?

Edit:
Thank you all for the quick and helpful replies. I got it working now. It was because I had to reset the counter.
I have come to ask for help as my professor is not giving me the help I need. I am new to c++ and I am trying to program a program that displays all the integers from 1 to 100 that are divisible by 6 or 7, but not both. and I have to display 5 numbers per row. I got it working except I have blank lines forming in certain areas. I don't know if it's because of how I set up the counter or what.
Here is what I got.
#include <iostream>
using namespace std;
int main()
{
int counter = 0; // Counter for creating new lines after 5 numbers
for (int numRange = 1; numRange <= 100; ++numRange) // Starts the loop of number 1 to 100
{
if (numRange % 6 == 0 || numRange % 7 == 0) // Makes the numbers divisible by 6 and 7
{
cout << numRange << " "; // Displays the output of the divisible numbers
counter++; // Starts the counter
}
if (counter % 5 == 0) // using the counter to create new lines after 5 numbers displayed
{
cout << endl; // Creates a new line
}
}
return 0;
}
This is what is outputted:
6 7 12 14 18
21 24 28 30 35
36 42 48 49 54
56 60 63 66 70
72 77 78 84 90
91 96 98
and this is what it's supposed to look like
6 7 12 14 18
21 24 28 30 35
36 48 49 54 56
60 63 66 70 72
77 78 90 91 96
98
The problem that you're seeing is due to the fact that you are checking for "5 outputs" on every loop, rather than only on ones where a number has been output! So, to fix this issue (there are others), put the counter % 5 == 0 test inside the preceding if block:
for (int numRange = 1; numRange <= 100; ++numRange) // Starts the loop of number 1 to 100
{
if (numRange % 6 == 0 || numRange % 7 == 0) // Makes the numbers divisible by 6 and 7
{
cout << numRange << " "; // Displays the output of the divisible numbers
counter++; // Increments the counter
if (counter % 5 == 0) // Only need this if we have done some output!
{
cout << endl; // Creates a new line
}
}
}
Another problem is that, in this requirement:
that are divisible by 6 or 7, but not both
your code doesn't check for the "but not both" part (but that's not the 'title' question, and I'm not going to do all your homework in one fell swoop).

Reading numbers from file to multidimensional arrays

I have integer numbers in a text file to be assigned to an array C[5][100].
My data is in this format:
17 40 35 24 50 15 31 38 48 18 16 44
41 10 26 50 48 20 24 12 48 24 34 39
...............
I am trying the code below but the error I get is this:
ValueError: cannot copy sequence with size 1005 to array axis with dimension 100
text_file = open("c051001.txt", "r")
C=np.zeros((5,100))
for i in range(agent):
C[i,]=map(int, (value for value in text_file.read().split()))
Number of integers in the file is more than 500 but I want to assign the remainder of numbers to another array.
You need to divide the data into appropriate chunks. A simple way to do this could be:
agent = 5
resource = 1
sz = 100
C = np.zeros((agent, sz))
idx = 0
chunk = sz
for i in range(agent):
C[i, ] = list(map(int, data[idx:idx + chunk]))
idx += chunk
# Assign the following 500 integers into another array of A[5,100,1]
A = np.zeros((agent, sz, resource))
for k in range(resource):
for i in range(agent):
A[i, :, k] = list(map(int, data[idx:idx + chunk]))
idx += chunk
trailing_data = data[idx:]

Why does this new [ ] and delete [ ] implementation break down for integers > 12?

The problem: I need to print the Pascal triangle for any (unsigned int) input passed as a command line argument. All the values must be stored in a LINEAR array and elements must only be manipulated as dereferenced pointers. Following this, the array elements must printed as a lower triangular matrix and subsequently deleted. My implementation functions perfectly for input ranging from 0 to 12 but produces spurious results for higher values.
I tried two different implementations.
Declare a pointer to an array of size (n+1)*(n+2)/2 (which is the number of elements in the triangle for input 'n'). Assign/print variables within a nested loop. Delete the pointer once both loops have been executed.
Run a nested loop, 0 <= i <= n, and 0 <= j <= i. Declare a pointer to an array of size (i+1) in the outer loop. Assign/print elements in the inner loop. Delete the pointer once the inner loop has been executed.
// VERSION 1
unsigned N = (n+1)*(n+2)/2;
unsigned* elements = new unsigned[N];
for(i = 0; i <= n; i++) {
for(j = 0; j <= i; j++) {
*(elements + j+(i*i+i)/2) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
cout << endl;
}
delete [] elements;
// VERSION 2
for(i = 0; i <= n; i++) {
unsigned* elements = new unsigned[i+1];
for(j = 0; j <= i; j++) {
*(elements + j) = fact(i) / (fact(j) * fact(i-j));
// print statement
}
delete [] elements;
cout << endl;
}
Both these versions were tried separately on Xcode. In both cases, the triangle printed correctly until the 12th layer, i.e. n=12, but generated incorrect results for higher values.
0 | 1
1 | 1 1
2 | 1 2 1
3 | 1 3 3 1
4 | 1 4 6 4 1
5 | 1 5 10 10 5 1
6 | 1 6 15 20 15 6 1
7 | 1 7 21 35 35 21 7 1
8 | 1 8 28 56 70 56 28 8 1
9 | 1 9 36 84 126 126 84 36 9 1
10 | 1 10 45 120 210 252 210 120 45 10 1
11 | 1 11 55 165 330 462 462 330 165 55 11 1
12 | 1 12 66 220 495 792 924 792 495 220 66 12 1
13 | 1 4 24 88 221 399 532 532 399 221 88 24 4 1
14 | 1 0 1 5 14 29 44 50 44 29 14 5 1 0 1
15 | 1 1 0 0 2 4 7 9 9 7 4 2 0 0 1 1
16 | 1 0 0 0 0 4 0 1 1 1 0 4 0 0 0 0 1
The debugger, to the extent that I can use it, produced no error messages.
What is happening and how do I fix it?
fact(i) overflows really fast. I haven't checked the numbers, but I'm pretty sure that's what's happening.
Instead, use the fact that a number in Pascal's triangle is the sum of the two numbers above it.
Wikipedia has a nice animation for this.
When i is 13, fact(i) is 6227020800, which is too big to fit in a 32-bit unsigned integer, so integer overflow occurs.

Decimate vector in eigen

I have a float array Eigen::ArrayXf which I need to decimate (i.e. pick 1 out of f.i. 8 samples).
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0, Eigen::InnerStride<8> >(signal.data(), length, 1).eval();
which works, with a caveat: I need to know how long length is, and it can be specified too long, leading to runtime errors.
Q: is there a way to decimate all that is possible, so that resultant length is == signal.size() / 8 ?
Two things. You are using the c'tor for mapping a matrix:
Map (
PointerArgType dataPtr,
Index nbRows,
Index nbCols,
const StrideType & a_stride = StrideType()
)
Constructor in the dynamic-size matrix case.
Parameters
dataPtr pointer to the array to map
nbRows the number of rows of the matrix expression
nbCols the number of columns of the matrix expression
a_stride optional Stride object, passing the strides.
I think you want the c'tor for a vector:
Map ( PointerArgType dataPtr,
Index a_size,
const StrideType & a_stride = StrideType()
)
Constructor in the dynamic-size vector case.
Parameters
dataPtr pointer to the array to map
a_size the size of the vector expression
a_stride optional Stride object, passing the strides.
The second thing is that you want length == signal.size())/8. Is that always a whole integer, or are you rounding up? If the data is 16 in length and you want the positions [0] and [8], then use 1+(signal.size()-1)/8 as the length parameter:
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0, Eigen::InnerStride<8> >(signal.data(), 1+((signal.size()-1)/8) ).eval();
For example:
#include <Eigen/Core>
#include <iostream>
using std::cout;
using std::endl;
int main(int argc, char *argv[])
{
Eigen::VectorXf signal;
signal.setLinSpaced(64, 0.0, 63.);
cout << "Original signal:" << endl << signal.transpose() << endl;
Eigen::ArrayXf decimatedSignal = Eigen::Map<Eigen::ArrayXf, 0,
Eigen::InnerStride<8> >(signal.data(), 1+((signal.size()-1)/8)).eval();
cout << endl << "Decimated:" << endl << decimatedSignal.transpose() << endl;
return 0;
}
outputs
Original signal:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Decimated:
0 8 16 24 32 40 48 56
which I think is exactly what you want.