Adding integers per line and storing it in array - c++

I'm trying to create a mini function using dynamically allocated arrays instead of vectors because I'm trying to figure out how they work exactly.
So basically, the user enters how many number of lines they want, and then after that, they enter in a group of integers/doubles separated by a space. Then, I want the function to calculate the total sum of integers in each line, allocate it into the array.
For example:
3
1 2 3 4
3 2 2 1 //assume each line has the same # of integers (4)
1 4 4 1
Then, if I implemented my function the total of sum would then be 10, 8, 10.
So far, I have this:
int* total //is there a difference if I do int *total ??
int lines;
std::cout << "How many lines?;
std::cin >> lines;
total = new int[lines];
for (int i=0;i<lines;i++)
{
for (int j=0;j<4;j++)
{
total[i] = ? //i'm confused how you add up each line and then put it in the array, then go onto the next array..
}
}
If anything does not make sense, please feel free to ask! Thank you!

you probably will want to set total[i] to 0 right before the inner loop, and then just use operator+= to add anything you get from the std::cin stream.
// ...
total[i]=0;
for (int j=0;j<4;j++)
{
int temp;
cin >> temp;
total[i] += temp;
}
// ...
It could be a bit easier to understand if you first allocated an array to store the values and then added them together.

First of all you need to allocate an array of arrays to store numbers of each line. For example
const size_t COLS = 4;
size_t rows;
std::cout << "How many lines? ";
std::cin >> rows;
int **number = new int *[rows];
for ( size_t i = 0; i < rows; i++ )
{
number[i] = new int[COLS];
}
int *total = new int[rows];
// or int *total = new int[rows] {}; that do not use algorithm std::fill
std::fill( total, total + rows, 0 );
After that you should enter numbers and fill each row of number.

There really isn't any difference between doing int* total and int *total (in your example anyways). Personally, I prefer the second one.
As for your question, you would need to set your total to an initial value (in this case you would set it to zero) and then from there just add onto it after getting the value from cin.
With cin, since you have the spaces, it will get each individual number (as you know, I'm assuming) however you probably should (I would) store that number into another variable and then add that variable onto the total for that row.
I think that all makes sense. Hope it helps.

IMHO you can do it using a 2 dimensional array:
int** total;
// ...
total = new int*[lines];
for(int i = 0; i < lines; ++i)
{
total[i] = new int[4]; // using magic number is not good, but who cares?
for(int j = 0; j < 4; ++j)
{
int tmp;
std::cin>>tmp;
total[i][j] = tmp;
}
}
// do sth on total
for(int i = 0; i < lines; ++i)
delete[] total[i];
delete[] total;

Related

Deleting elemnt from array and calculating sum

Number can't be in array if it can be divided by number of elements of array (for example: in array which has 10 elements, numbers 1,2,5 and 10 are not "welcome"). So I need to find all these elements in array and kick them out. After that length of array changes, and then some other elements can be "not welcome" in array. I have to repeat it until array is without these elements. In the end, I have to calculate remaining elements and print them out. (I'm using C++)
I didn't know how to delete element from array, and just set value to 0.
I get input n (number of elements in array) and then all of these elements.
So, I already tried it but I'm sure there is much more effective way to do it :P Here is the code:
int main()
{
short int b = 0;
short int n;
int result = 0;
cin >> n;
int m = n;
int numbers[n];
for (int i = 0; i < n; i++) {
cin >> numbers[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j<=n; j++) {
if(numbers[j] != 0) {
if(n % numbers[j] == 0) {
numbers[j] = 0;
b = b + 1;
} }
}
n = n - b;
b = 0;
}
for (int i = 0; i < m; i++) {
result += numbers[i];
}
cout << result;
return 0;
}
example input: 10 1 2 3 4 5 6 7 8 9 10
example output: 24
I didn't know how to delete element from array
It is not possible to "delete element from array". An array of n elements begins its life with n elements, has n elements throughout its entire lifetime, and ends its life with n elements. It is not possible to change the size of an array.
Another problem:
cin >> n;
int numbers[n];
The size of an array must be a compile time constant. n is not a compile time constant. This is not a well-formed C++ program.
An array of runtime size must be allocated dynamically. The easiest solution is to use std::vector. The size of a vector can change, and you can use std::vector::erase to remove elements from it.

How to fix this code while using dynamic 2D array

I'm using dynamic 2D array and need the value of particular index but it is not printing the correct value.
```int u=5;//No. of elements
int S[u];
int i=0;
while(i<u)//elements in universal set
{
cin>>S[i];
i++;
}
int n;
cin>>n;//no. of subset
i=0;
int subcost[n];
int **subset;
subset=new int*[n];
while(i<n)
{
int l,c;
cin>>l;//size of ith subset
subset[i]=new int[l];
int j=0;
while(j<l)//Elements in each subset
{
cin>>subset[i][j];
j++;
}
cin>>c;//cost for each subset
subcost[i]=c;
i++;
}
i=0;
while(i<n)
{
int j=0;
int s=*subset[i];
while(j<s)
{
cout<<subset[i][j]<<"\n";
j++;
}
i++;
}```
I expect the output to be value of each subset, but the actual output is totally different.
arr[i]=new int[n1];
There's a misunderstanding of what new does. (Perhaps you come from Java?) This doesn't store an integer with the value of n1. It instead creates an array with a size of n1.
Just one pointer level should be enough for an array:
int n = 5;
int i = 0;
int *arr;
arr = new int[n];
arr[i] = 100;
cout << arr[i] << endl; // output: 100
delete[] arr; // remember to deallocate – otherwise memory leaks will haunt your system!
If you're looking for a 2D array, a pointer to a pointer (**) will work.
int **arr;
arr = new int[n]; //
arr[0] = new int[n]; // allocate first array
arr[0][0] = 100; // set first element of first array
delete[] arr[0];
delete[] arr; // deallocate
Here
arr[i]=new int[n1]; /* allocating memory for arr[i], equal to n1*sizeof(int) bytes & arr[i] gets points to address returned by new */
cout<<"Value of "<<i<<"th row is :- "<<arr[i]<<"\n";
I expect the output to be value of n1, but the actual output is some
random address ?
yes, arr[i] is dynamically created array & printing it will prints its base address only.
Try this version where I tried to explain code changes in comments.
int main(void) {
std::cout<<"Enter the value of n"<<"\n";
int n;
std::cin>>n;
int **arr;
/* allocate memory for arr. arr holds base address of array of n int ptr */
arr=new int*[n];
int i=0;
int n1;
std::cout<<"Enter the value of n1"<<"\n";
std::cin>>n1;
/* allocate memory for arr[0], arr[1] .. */
while(i < n1) {
arr[i]=new int[n1];
i++;
}
/* put the data into dynamically allocated array */
for(int row = 0; row < n; row++) {
for(int col = 0; col < n1; col++) {
std::cin>>arr[row][col];
}
}
/* printh te data */
for(int row = 0; row < n; row++) {
for(int col = 0; col < n1; col++) {
std::cout<<"Value of "<<i<<"th row is :- "<<arr[row][col];
}
std::cout<<"\n";
}
return 0;
}
And since you created dynamic array using new you need to free the dynamically allocated memory to avoid memory leakage, use delete operator accordingly.
As pointed by others std::vector is better option than above one.
While you have a good answer from #Achal for dynamically allocating, as mentioned, you really should use the container vector provided by C++ to make things much easier and more robust. All C++ containers provided automatic memory management freeing you from having to allocate manually (and with much less chance of getting it wrong)
When using containers, such as a vector of vectors to store your data, you can simply read and discard your "//elements in universal set", "//no. of subset" and "//Elements in each subset". Those values are not required when using containers. You simply read the value you want and add it to your container, the container will grow as needed to accommodate.
While it is not 100% clear what your input data looks like, we can deduce from your file it looks something like:
Example Input File
Where your first integers is your "//elements in universal set" which isn't needed to read the data. Likewise the second line, your "//no. of subset" is irrelevant for reading the data. Finally the 1st element on each data row, your "//Elements in each subset" is also not needed. Each of these values is simply read and discarded to arrive at your final data set.
$ cat dat/universal_sub.txt
5
4
5 1 2 3 4 5
3 1 2 3
4 1 2 3 4
6 1 2 3 4 5 6
The Final Dataset You Want To Store
From the full file, these appear to be the actual data values you want to store (there can be an even number, but there is no requirement for that)
1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6
There are many different ways you can put the pieces together. A short example of how to get your final dataset from your input file could be:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <limits>
int main (void) {
std::string line; /* string for reading each line */
std::vector<std::vector <int>> subset; /* vector<vector<int>> */
int universal, nsubsets; /* two int to read/discard */
if (!(std::cin >> universal >> nsubsets)) { /* read/dicard 2 values */
std::cerr << "error: failed to read universal.\n";
return 1;
}
/* read/discard '\n' (any chars) left in input buffer line by cin above */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');
while (getline (std::cin, line)) { /* read each remaining data line */
int unneeded, i; /* 1st value and i for rest */
std::vector<int> tmp; /* vector<int> for each line */
std::stringstream ss (line); /* stringstream to read from */
if (ss >> unneeded) { /* read/discard 1st value */
while (ss >> i) /* read rest from stringstream */
tmp.push_back(i); /* add to tmp vector */
subset.push_back(tmp); /* add tmp vector to subset */
}
}
for (auto& i : subset) { /* loop over subsets */
for (auto& j : i) /* loop over each value in subset */
std::cout << " " << j; /* output value */
std::cout << '\n'; /* tidy up with newline */
}
}
(note: the output loops make use of the Range-based for loop (since C++11) but you are free to use the .begin() and .end() container functions with a traditional for loop if your compile does not support std=c++11)
Exaple Use/Output
Reading your data into a vector of vectors allows accessing each element:
$ ./bin/vector_2d_subset < dat/universal_sub.txt
1 2 3 4 5
1 2 3
1 2 3 4
1 2 3 4 5 6
Look things over and let me know if you have further questions or if I interpreted your data file format incorrectly.

Deallocating memory of a 2D array of pointers only till a certain limit

I have a 2D array created dynamically using pointer. I want to delete only certain continuous rows, not all of them. Here is the code I have written for deleting:
#include <iostream>
using namespace std;
void clearMemoryAll(int **matchedIndicesArray, int rows)
{
for(int i = 0; i < rows; i++)
{
delete [] matchedIndicesArray[i];
}
delete [] matchedIndicesArray;
}
int main()
{
// Program having 10M x 4 = 40M elements
int rows = 10000000;
int **matchedStagesMatrix;
matchedStagesMatrix = new int*[rows];
int cols = 4;
for(int i = 0; i < rows; i++)
{
matchedStagesMatrix[i] = new int[cols];
for (int j = 0; j < cols; j++)
{
matchedStagesMatrix[i][j] = 1;
}
}
clearMemoryAll(matchedStagesMatrix, rows);
while (1) {}
return 0;
}
Clearly, this code is gonna delete ALL the rows of the 2D array. How do I delete only certain first 100 rows instead of all at once? I can't simply pass 100 as a parameter to the function since it'd anyways try to delete complete matrix when the control reaches outside the function's for loop. The matrix should be deleted such that it should still be usable after deleting certain rows.
I understand vectors is a good alternative, but I'm curious about how pointers work and how they can be manipulated instead of using vectors.
Edit: Also, I plan to use this delete function numerous times, i.e. I'd be deleting the matrix rows one by one numerous times, each time only certain few rows until all the rows are deleted. Therefore, the last line outside for loop cannot be executed every time.
This can be done if you use vectors, which are easier to handle thanks to their methods.
int n,x;
std::cin>>n>>x;
std::vector<int*> myVec;
int* row=new int[n];
for(int i=0;i<n;i++)
std::cin>>row[i];
myVec.push_back(row);
//do this for all your rows;
myVec.erase(myVec.begin(),myVec.end()+x); //delete first x rows;
//you can play with the line above to delete lines in a range or sth
There are other ways to do the task that you want to do, but let's say that we stick to the way that you have discussed in the question.
If you delete a certain row, you need to remember which row you deleted and make sure not to access it again.
For this, you can maintain an array of flags, which has the size equal to number of rows. The flags are all 0 at first.
Example - If there are total 10 rows in the 2D array, then
int flag[rows] = 0;
When you delete a certain row, you can change the value of flag for that row to 1.
Example - if we delete 4th row, then
flag[3] = 1;
After that whenever you have to traverse through the 2D array, you can just skip the row which has value of flag equal to 1.
Here, is the sample code, modified by me:
#include <iostream>
using namespace std;
void printArray(int **matchedIndicesArray,int flag[], int rows, int cols)
{
for(int i=0; i<rows; i++)
{
if(flag[i]==1) //if flag for the row is 1, that means it is deleted, and so we skip it
{
continue;
}
for(int j=0; j<cols; j++)
{
cout<<matchedIndicesArray[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
void clearMemorySome(int **matchedIndicesArray, int flag[], int rows)
{
for(int i = 0; i < rows/2; i++) //here I chose to delete half the rows
{
delete [] matchedIndicesArray[i];
flag[i] = 1; //to remember which row has been deleted, we change the value of flag to 1
}
return;
//delete [] matchedIndicesArray; //this is commented out because we are only deleting certain rows at a time
}
int main()
{
// Program having 10 * 3 = 30 elements
int rows = 10;
int **matchedStagesMatrix;
matchedStagesMatrix = new int*[rows];
int cols = 3;
int flag[rows]={0}; //initially the flag value for every row is 0
for(int i = 0; i < rows; i++)
{
matchedStagesMatrix[i] = new int[cols];
for (int j = 0; j < cols; j++)
{
matchedStagesMatrix[i][j] = 1;
}
}
cout<<"The 2D array before half of the rows are deleted\n";
printArray(matchedStagesMatrix, flag, rows, cols);
clearMemorySome(matchedStagesMatrix, flag, rows);
cout<<"The 2D array after half of the rows are deleted\n";
printArray(matchedStagesMatrix, flag, rows, cols);
return 0;
}
The output of the above code is:
The 2D array before half of the rows are deleted
1 1 1 1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
The 2D array after half of the rows are deleted
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1

printing a 2d array read from a txt file displays wrong in c++

i am new to c++ and i would really appreciate some help with my following problem:
i have dynamically allocated space for a 2d int array of N rows and two columns the following way :
int **input;
input = new int *[N];
for (int count = 0; count < N; count++)
input[count] = new int[2];
when i print its contents in the while-loop in which i "fill" the array the actual contents are printed :
while (!myfileafter.eof())
{
int temp1,temp2;
int i=0;
int j=0;
myfileafter >> temp1>>temp2;
input[i][j]=temp1;
input [i][j+1] = temp2;
i++;
j=0;
cout<<input[i-1][j]<<" "<<input[i-1][j+1]<<endl;
}
// for (int p=0;p<N;p++)
// cout<<input[p][0]<<" "<<input[p][1]<<endl;
however , if i use the two commented-out lines just after the while loop the array seems to contain totally different contents than the right ones printed before and this is the cause of many problems in the rest of the programm . any idea how can this be solved?
It seems that the contents of the file do not match with the length of your array.
Try this:
int temp1,temp2;
int i=0;
int j=0;
while ( i < N && myfileafter >> temp1>> temp2 )
{
input[i][j]=temp1;
input[i][j+1] = temp2;
i++;
j=0;
cout<<input[i-1][j]<<" "<<input[i-1][j+1]<<endl;
}
// Note the termination condition. It is uncertain whether all N locations have been filled.
for (int p=0;p<i;p++)
cout<<input[p][0]<<" "<<input[p][1]<<endl;
EDIT: Instead of using a 2D Nx2 array, I would suggest you to use 2 1D arrays to avoid possible errors and for code clarity. Or better still, use two 1D vectors.
With pointers you will have to take care of deleting the allocating memory.
At the beginning of the loop you set i to zero, so you're always reading into input[0].
It's better to use the actual reading as the condition:
int i = 0;
while ( my_file_after >> input[i][0] >> input[i][1] ) ++i;
The first thing I'd recommend is to practice formatting your code more consistently. There are some accepted conventions that can make your code a lot more readable. Only changing formatting, I'd recommend something like this:
while (!myfileafter.eof())
{
int temp1,temp2;
int i=0;
int j=0;
myfileafter >> temp1 >> temp2;
input[i][j] = temp1;
input [i][j+1] = temp2;
i++;
j=0;
cout << input[i-1][j] << " " << input[i-1][j+1] << endl;
}
//for (int p=0; p < N; p++)
//{
// cout << input[p][0] << " " << input[p][1] << endl;
//}
I'm sure it's also possible that you formatted it correctly and it just got messed up when you entered it here, but proper formatting can make a world of difference.
Moving on... gahh! Carl beat me to it: you're overwriting input[0] every time.
The only thing I'll add is that the cout inside your loop is a bit deceptive because it will print out what you expect it to, but it's printing it from input[0][0] and input[0][1] every time.
Ok, there are other answers here that explain what is wrong with your code specifically, but I'll also add some other information about how you're approaching the array allocation itself.
Typically speaking, an array (unless it's some STL or other intelligent/class array) is a contiguous piece of memory. Then an additional array points to that. In other words, for foo[X][Y] you're creating foo[X] first then adding the [Y] component after the fact, individually, instead of creating a contiguous [X*Y] piece of memory then having each foo[X] element point to the first element of each [Y]. Visually, you're doing this:
foo -|
|
|
| [...]
then each int individually like
foo -| -- _
|_
| -- _
|_
| -- _
|_
| [...]
when you should be allocating the entire int chunk as one piece because 1) if you do a lot of small allocations like this it tends to kill performance (not that important for you here I don't think) and b) pointer arithmetic will actually work if the array is properly created.
Let's say you have the following chunks:
foo is an array of int* that starts at ADDRESS_X and is 4 elements long. For your example you need 4 elements * 2 columns = 8 ints total. So you create a contiguous 8 int long array that starts at ADDRESS_Y. You'd then want to do this (pseudocode-ish here):
int **foo = new int *[SIZE_OF_X]; // an array of 4 pointers
int *bar = new int[SIZE_OF_X * NUMBER_OF_COLUMNS]; // in other words, 8 ints
for (i = 0; i < SIZE_OF_X; i++) {
foo[i] = &bar + (i * SIZE_OF_X);
}
Where bar is:
ADDRESS_Y + 0: 10
ADDRESS_Y + 1: 20
ADDRESS_Y + 2: 30
...
And foo is:
ADDRESS_X + 0: ADDRESS_Y
ADDRESS_X + 1: ADDRESS_Y + 2
...
so foo[1][0] == 30.

Swap elements in array to reverse an array

I got an assignment to reverse an dynamic array in C++. So far, from my logic, I thinking of loop thru the array to reverse it. And here comes my code :
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< sizeof(num_array)/sizeof(num_array[0]) ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array[size],size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], int size)
{
for (int count =0; count< sizeof(num_array)/sizeof(num_array[0]); count++){
cout << num_array[sizeof(num_array)/sizeof(num_array[0])-1-count] << " " ;
}
return;
}
Somehow I think my logic was there but this code doesn't works, there's some error. However, my teacher told me that this isn't the way what the question wants. And here is the question :
Write a function reverse that reverses the sequence of elements in an array. For example, if reverse is called with an array containing 1 4 9 16 9 7 4 9 11,
then the array is changed to 11 9 4 7 9 16 9 4 1.
So far, she told us in the reverse method, you need to swap for the array element. So here's my question how to swap array element so that the array entered would be reversed?
Thanks in advance.
Updated portion
int main ()
{
const int size = 10;
int num_array[size];
srand (time(NULL));
for (int count = 0; count< size ; count++){
/* generate secret number between 1 and 100: */
num_array[count] = rand() % 100 + 1;
cout << num_array[count] << " " ;
}
reverse(num_array,size);
cout << endl;
system("PAUSE");
return 0;
}
void reverse(int num_array[], const int& size)
{
for (int count =0; count< size/2; count++){
int first = num_array[0];
int last = num_array[count-1];
int temp = first;
first = last;
last = temp;
}
}
You reverse function should look like this:
void reverse(int* array, const size_t size)
{
for (size_t i = 0; i < size / 2; i++)
{
// Do stuff...
}
}
And call it like:
reverse(num_array, size);
I am no C++ programmer, however I do see an easy solution to this problem. By simply using a for loop and an extra array (of the same size) you should be able to reverse the array with ease.
By using a for loop, starting at the last element of the array, and adding them in sequence to the new array, it should be fairly simple to end up with a reversed array. It would be something like this:
Declare two arrays of the same size (10 it seems)
Array1 contains your random numbers
Array2 is empty, but can consist of 10 elements
Also declare an integer, which will keep track of the progression of the for loop, but in the opposite direction. i.e not from the end but from the start.
Counter = 0
Next you will need to create a for loop to start from the end of the first array, and add the values to the start of the second array. Thus we will create a for loop to do so. The for loop will be something like this:
for(int i = lengthOfArray1; i > 0; i--){
Array2[Counter] = Array1[i]
Counter++
}
If you only wish to print it out, you would not need the counter, or the second array, you will simply use the Array1 elements and print them out with that style of for loop.
That's it. You could set Array1 = Array2 afterward if you wished to keep Array1 the original for some reason. Hope this helps a bit, changing it to C++ is your job on this one unfortunately.
You're not actually swapping the elements in the array, you're just printing them out. I assume she wants you to actually change what is stored in the array.
As a hint, go through the array swapping the first and last element, then the 2nd and 2nd last element, etc. You only need to loop for size/2 too. As you have the size variable, just use that instead of all the sizeof stuff you're doing.
I would implement the function like following
void reverse(int A[], int N)
{
for (int i=0, j=N-1; i<j; i++, j--){
int t = A[i];
A[i] = A[j];
A[j] = t;
}
}