Sum up vector and insert function for 2d vector

Hi all. I got a task to sum up 2d vector. But each time the amount of the summation reaches 50, I need to insert the value of 0 and sum up the next number until finish.

I have 2 text file data as follows

First, original data:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
0 0 4 3 2 1 15 14 13 12 11 14 13 12 11 10
0 1 5 7 8 9 3 4 6 9 18 11 5 7 9
0 14 13 12 11 10 9 8 7 6 5 4 3 2 1
0 0 7 9 5 11 13 15 17 19 5 7 4 9 3 2

Second, temporary data:
0 10 20 15 25 5 10 10 8 14 16 11 6 8 9
0 0 25 18 15 6 9 15 5 10 30 6 10 15 6 8
0 10 10 10 15 5 18 18 8 5 13 15 6 14 1
0 10 30 10 25 5 20 15 9 15 9 10 10 15 7
0 0 9 19 20 10 30 8 16 15 9 10 18 5 9 7

The procedure can be illustrated as follows:
For each row, I need to sum up temporary vector. Each time the summation reach 50 or near to 50 (<=50), I need to insert 0. Then, insert 0 at the end of each row.

Example for row 0 of temporary vector,
0 10 20 15 0 25 5 10 10 0 8 14 16 11 0 6 8 9 0

Instead of inserting 0 in the temporary vector. I also need to insert 0 in the original vector, which mean insert 0 at the same place as temporary vector.

Example for row 0 of original data,
0 1 2 3 0 4 5 6 7 0 8 9 10 11 0 12 13 14 0

I had write the code to read and display the text file data, but when I run the program, it display the wrong solution, not the same as in the data.

Also, when I try to insert 0 for original vector, error occurred (debug assertion failed).

Hopefully someone could help me. If further explanation regards to the code is needed, please let me know.

Any advice greatly appreciated.

Here is the code.
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream> 
#include <fstream>
#include <vector>  
#include <algorithm>

using namespace std; 

const int row = 5;
const int col = 16;

vector<vector<int> > vec(row, vector <int>(col, 0));
vector<vector<int> > vec_temp(row, vector <int>(col, 0));

int main () 
{ 
    // Input file
	ifstream inpOriData("ori_data.txt");
	ifstream inpTempData("temp_data.txt");

	// Assign ori data into array 
	cout << "Original vector: "; 
		cout << endl;
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < vec[i].size(); j++)
		{
			inpOriData >> vec[i][j];
			cout << vec[i][j] << '	';
		}
		cout << endl;
	}
	cout << endl;

	// Assign temp data into array 
	cout << "Temporary vector: "; 
		cout << endl;
	for (int i = 0; i < vec_temp.size(); i++)
	{
		for (int j = 0; j < vec_temp[i].size(); j++)
		{
			inpTempData >> vec_temp[i][j];
			cout << vec_temp[i][j] << '	';
		}
		cout << endl;
	}
	cout << endl;
      
    // Close input files
	inpOriData.close(); 
	inpTempData.close(); 

	int sum = 0;
	int Q = 50;

	for(int i = 0; i < vec_temp.size(); i++)
	{
		// Iterator used to store the position of searched element 
		vector<int>::iterator itr; 
	
		for (itr = vec_temp[i].begin(); itr != vec_temp[i].end(); itr++)
		{
			if (sum + *itr > Q)
			{
				// inserting an element invalidates the iterator, get a new one (for both vector)
				itr = vec_temp[i].insert(itr, 0);
				//itr = vec[i].insert(itr, 0);		
				sum = 0;
			}
			sum += *itr;
		}
		// add on a final zero to end out the series for both vector
		vec_temp[i].push_back(0);
		//vec[i].push_back(0);
	}

	// Print new vector for temporary vector
    cout << "New vector for temporary: ";
		cout << endl;
    for (int i = 0; i < vec_temp.size(); i++)
	{
		for (int j = 0; j < vec_temp[i].size(); j++)
		{
			cout << vec_temp[i][j] << '	';
		}   
		cout << endl;
	}
	cout << endl;

	// Print new vector for original vector
    cout << "New vector for original: ";
		cout << endl;
    for (int i = 0; i < vec.size(); i++)
	{
		for (int j = 0; j < vec[i].size(); j++)
		{
			cout << vec[i][j] << '	';
		}   
		cout << endl;
	}
	cout << endl;

    system("pause");
    return 0; 
} 
One way to do this:
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <vector>
#include <iomanip>

void insert_zeroes( std::vector<int>& original_row, std::vector<int>& temporary_row, int limit )
{
    if( original_row.size() == temporary_row.size() )
    {
        std::vector<int> modified_original_row ;
        std::vector<int> modified_temporary_row ;

        int sum_so_far = 0 ;
        for( std::size_t i = 0 ; i < original_row.size() ; ++i )
        {
            if( temporary_row[i] > limit ) return ; // error in data: give up

            sum_so_far += temporary_row[i] ;
            if( limit < sum_so_far ) // if sum exceeds limit
            {
                // append zeroes before writing these values
                modified_original_row.push_back(0) ;
                modified_temporary_row.push_back(0) ;
                sum_so_far = temporary_row[i] ; // and reinitialise sum_so_far
            }

            modified_original_row.push_back( original_row[i] ) ;
            modified_temporary_row.push_back( temporary_row[i] ) ;
        }

        // append the final zeroes
        modified_original_row.push_back(0) ;
        modified_temporary_row.push_back(0) ;

        // finally, update the rows passed by reference
        original_row.swap(modified_original_row) ;
        temporary_row.swap(modified_temporary_row) ;
    }
}

void insert_zeroes( std::vector< std::vector<int> >& original,
                    std::vector< std::vector<int> >& temporary,
                    int limit = 50 )
{
    if( original.size() == temporary.size() )
    {
        for( std::size_t i = 0 ; i < original.size() ; ++i )
            insert_zeroes( original[i], temporary[i], limit ) ;
    }
}

void print( const std::vector<int>& vec )
{
    for( int v : vec ) std::cout << std::setw(4) << v ;
    std::cout << '\n' ;
}

void print( std::vector< std::vector<int> >& mtx )
{
    for( const auto& row : mtx ) print(row) ;
    std::cout << '\n' ;
}

int main()
{
    std::vector< std::vector<int> > original =
    {
        { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 },
        { 0, 0, 4, 3, 2, 1, 15, 14, 13, 12, 11, 14, 13, 12, 11, 10 },
        { 0, 1, 5, 7, 8, 9, 3, 4, 6, 9, 18, 11, 5, 7, 9 },
        { 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 },
        { 0, 0, 7, 9, 5, 11, 13, 15, 17, 19, 5, 7, 4, 9, 3, 2 }
    };
    print(original) ;

    std::vector< std::vector<int> > temporary =
    {
        { 0, 10, 20, 15, 25, 5, 10, 10, 8, 14, 16, 11, 6, 8, 9 },
        { 0, 0, 25, 18, 15, 6, 9, 15, 5, 10, 30, 6, 10, 15, 6, 8 },
        { 0, 10, 10, 10, 15, 5, 18, 18, 8, 5, 13, 15, 6, 14, 1 },
        { 0, 10, 30, 10, 25, 5, 20, 15, 9, 15, 9, 10, 10, 15, 7 },
        { 0, 0, 9, 19, 20, 10, 30, 8, 16, 15, 9, 10, 18, 5, 9, 7 }
    };
    print(temporary) ;

    insert_zeroes( original, temporary, 50 ) ;
    std::cout << "\nafter inserting zeroes\n----------------------\n\n" ;
    print(original) ;
    print(temporary) ;
}

http://coliru.stacked-crooked.com/a/0d09e13909f3e685
Hi JLBorges,

Thank you for your help and the code you provided. It seems hard for me to understand it. I will try to understand it and maybe take some time. For the time being, if you do not mind, with your help, can I know what's wrong with my program and how to fix it.

Thanks for your help and really appreciated.
can I know what's wrong with my program and how to fix it.

Even if I’m not the one you addressed your question to, I’d like to add my personal opinion.

Firstly, you code tries to solve only the first half of the assignment:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
for(int i = 0; i < vec_temp.size(); i++)
{
	vector<int>::iterator itr; 
	for (itr = vec_temp[i].begin(); itr != vec_temp[i].end(); itr++)
	{
		if (sum + *itr > Q)
		{
			itr = vec_temp[i].insert(itr, 0);
			//itr = vec[i].insert(itr, 0);		
			sum = 0;
		}
		sum += *itr;
	}
}

The above code tries to insert a number inside one of the two std::vectors you’re expected to update, not into both.
The commented line would fail because you cannot use an iterator pointing to a std::vector instance to access elements of another std::vector instance.

Secondly, your code is not split into functions, and that makes it look like a mess.

Thirdly, you don’t use functions (apart from main()), but you introduce global variables - to what avail?

You also use std::vectors as if they were C-style arrays - which is not a mistake, of course, but at least unexpected.

In the whole, it seems your teacher gave you an assignment about std::vector, iterators, insert() and push_back(), but you don’t master that stuff. Perhaps I’m wrong.

Unsolicited hints:
- you could either copy&paste your assignment text, so that we can read it, or explain better what you should do: are you required to load all data into the two std::vectors and then work on them, or you can elaborate data when you read them from the files?
That would lead to two different codes, I think.

- you could prettify your code with a typedef like this:
using vec2d = std::vector<std::vector<int>>;
and make everything easier to read.

- In case you need to read the two files and store their values before managing them, you could add a function which simply does that:
(just an example)
std::vector<std::vector<int>> loadDataIntoVec2d(const std::string& filename, int rows, int cols);

- Of course you could also add a function to print those std::vectors:
void print2DVector(const std::vector<std::vector<int>>& v);
(JLBorges already offered you an elegant overloaded solution)

- When you get through one of the two std::vector by an iterator, you need a second iterator, which keeps the pace with the first and performs the same operations on the other std::vector.
Didn't you already? Oh yes, you did: http://www.cplusplus.com/forum/beginner/250450/ http://www.cplusplus.com/forum/beginner/250593/
In other words, you have already "solved" simpler cases and should be able to build on them.

I got a task to sum up 2d vector.

I see no such thing, or we mean different things with "2d".

What I see is that one input contains two vectors and you insert elements to both vectors based on the content of one of the vectors. You repeat this for multiple inputs.

Nothing actually says that the data has to be in two vectors, does it?
One input could be a std::list<std::pair<int,int>>. Granted, that affects the input.
The benefit of using a list is cheap insertions.
The benefit of using a pair is "insertion to both vectors" with one operation. foo.emplace( pos, 0, 0 );
Hi keskiverto,

Yes i had post it before. First one insert in 1d array and the second post is insert in 2d array. But, now I need to insert it in two different vector at the same position. I had try it but the solution is wrong. I keep thinking how to do it. But i really dont know how to do it. That why i post it to ask. What wrong with my program. Hoping someone can tell me what wrong and how to fix it.

I dont know if i doing wrong by asking this. I just can't think how to fix it.
Enoizat wrote:
you cannot use an iterator pointing to a std::vector instance to access elements of another std::vector instance.

In other words:
1
2
3
auto gaz = foo.begin();
gaz = foo.emplace( gaz, 0 );
bar.emplace( gaz, 0 ); // ERROR: gaz is not an iterator to bar 


How to fix that?

My suggestion was to store corresponding "original" and "temporary" data values together as a std::pair.
Then you have only one vector and one iterator. Insertion to "1d array" you already know.

JLBorges appends to new vectors and therefore avoids the "insert to both" dilemma.

Option C:
You have iterator to Kth element of foo.
You need iterator to Kth element of bar.
The latter should be easy? bar.begin() + K, isn't it?
How to get K?
http://www.cplusplus.com/reference/iterator/distance/
Thanks keskiverto for your explanations. I will try to study on std::list, emplace, std::pair and iterator. I will try to fix my problem. I will come back if i got another question to ask.

Again, thank you for your help. I really apreciated it.
Hi keskiverto,
My suggestion was to store corresponding "original" and "temporary" data values together as a std::pair.
Then you have only one vector and one iterator. Insertion to "1d array" you already know.

Sorry for troubling you again. I had try writing the codes, but the program getting error when I want to enter values in vector of pairs.

If you don't mind. Can you check my codes. How can I fix the error?

And one more things, I have 2D data where each row is of different size. When I want to print the assigned data, I keep getting the wrong solution, not same as data in the text file.

For example, this is the original data from text file.

0	1	2	3	4	5	6	7	8	9	10	11    12	13	14 
0	0	4	3	2	1	15	14	13	12	11	14	13	12	11	10 
0	1	5	7	8	9	3	4	6	9	18	11	5	7	9 
0	14	13	12	11	10	9	8	7	6	5	4	3	2	1 
0	0	7	9	5	11	13	15	17	19	5	7	4	9	3	2 


The program display as below:

0       1       2       3       4       5       6       7       8       9       10      11      12      13      14
0
0       4       3       2       1       15      14      13      12      11      14      13      12      11      10
0
1       5       7       8       9       3       4       6       9       18      11      5       7       9       0
14
13      12      11      10      9       8       7       6       5       4       3       2       1       0       0
7
9       5       11      13      15      17      19      5       7       4       9       3       2       0       0
0


Any advice greatly appreciated.

Here is the code.
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
64
65
66
67
68
69
#include <iostream> 
#include <fstream>
#include <vector>  // for 2D vector 
#include <utility> // for pair

using namespace std; 

const int rows = 5;
const int cols = 16;

vector<vector<int> > original(rows, vector <int>(cols, 0));
vector<vector<int> > temporary(rows, vector <int>(cols, 0));
  
int main() 
{ 
    // Input file
	ifstream inpOriginal("original.txt");
	ifstream inpTemporary("temporary.txt");

	// Assign original data into array 
	cout << "Original vector:\n";
	for (int i = 0; i < original.size(); i++)
	{
		for (int j = 0; j < original[i].size(); j++)
		{
			inpOriginal >> original[i][j];
			cout << original[i][j] << '	';
		}
		cout << endl;
	}
	cout << endl;

	// Assign temporary data into array 
	cout << "Temporary vector:\n";
	for (int i = 0; i < temporary.size(); i++)
	{
		for (int j = 0; j < temporary[i].size(); j++)
		{
			inpTemporary >> temporary[i][j];
			cout << temporary[i][j] << '	';
		}
		cout << endl;
	}
	cout << endl;

	// Declaring vector of pairs 
    vector< vector<pair<int,int>>> vect( rows, vector<pair<int,int>>(cols) ); 
                                    
    // Entering values in vector of pairs
    for (int i = 0; i < vect.size(); i++)
    {
        for (int j = 0; j < vect[i].size(); j++)
        {
            vect.push_back( make_pair(original[i][j],temporary[i][j]) );
        }
    }
    
    // Displaying the vector
    for (int i = 0; i < vect.size(); i++)
    {
        for (int j = 0; j < vect[i].size(); j++)
        {
            cout << vect[i][j].first << " "
                 << vect[i][i].second << endl;
        }
    }
	system("pause");
	return 0;
}
You "get an error"?

More accurately, the compiler reports a syntax error. The error message might be:
54:71: error: no matching function for call to
  'std::vector<std::vector<std::pair<int, int> > >::push_back(std::pair<int, int>)'

Hopefully, there is some additional hints too, like:
note: no known conversion for argument 1
  from 'std::pair<int, int>'
  to 'const value_type& {aka const std::vector<std::pair<int, int> >&}'

You try to push a pair into a vector that holds vectors.


Note that you have a major logical error on lines 8 and 9:
1
2
const int rows = 5;
const int cols = 16;

You are absolutely sure that each file has 80 data values and that will be 16 values per row. Yet,
And one more things, I have 2D data where each row is of different size.

you know that the actual data does not.

The same fatal assumption continues on line 47:
vector< vector<pair<int,int>>> vect( rows, vector<pair<int,int>>(cols) );
The vect has 5 rows and 16 pairs per row to begin with (with default initialized pair objects).

Then you proceed to add (push_back) more ...


Look at the function by JLBorges:
1
2
3
4
void insert_zeroes(
        std::vector<int>& original_row,
        std::vector<int>& temporary_row,
        int limit )

Does it operate on vector<vector<int>>s? No. It takes only two vectors, because that keeps the code simpler.

Factoring the code into functions keeps it simple too.


Please write a function that reads integers from one line of stream into a vector.
1
2
3
4
std::istream& readrow( std::istream& in, std::vector<int>& row )
{
  // your code here
}
Input:Text.txt
11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19
11 12 13 14 15 16 17 18 19
Outout:Text1.txt
11 12 13 14 0 15 16 17 18 0 19
11 12 13 0 14 15 16 17 0 18 19
11 12 0 13 14 15 16 0 17 18 19 0
11 12 13 14 0 15 16 17 18 0 19
11 12 13 0 14 15 16 17 0 18 19
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
#include<istream>
#include<fstream>

using namespace std;
int main()
{
	
	int sum = 0;
	int a;
	ifstream f("Text.txt");
	ofstream f1("Text1.txt");
//if(!f.good())
//cout<<"File did not open"<<endl;
//f.close()
//if(!f1.good())
//cout<<"File did not open"<<endl;
//f1.close();
	while (!f.eof())
	{
		if (f.peek() == '\n')
			f1 << endl;
		f >> a;
		f1 << a<<' ';
		sum += a;
		if (sum >= 50)
		{
			f1 << 0<<' ';
			sum = 0;
		}

	}
	f.close();
	f1.close();
	
}
Last edited on
Hi keskiverto, it is possible for me to use std::pair, if I read data like this. I'm not really familiar by writing function. I new to c++. I'm a bit confuse now.

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
64
#include <iostream> 
#include <vector>  // for 2D vector 
#include <utility> // for pair

using namespace std;

int main()
{
	vector<vector<int> > original{ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 },
								   { 0, 0, 4, 3, 2, 1, 15, 14, 13, 12, 11, 14, 13, 12, 11, 10 },
								   { 0, 1, 5, 7, 8, 9, 3, 4, 6, 9, 18, 11, 5, 7, 9 },
								   { 0, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 },
								   { 0, 0, 7, 9, 5, 11, 13, 15, 17, 19, 5, 7, 4, 9, 3, 2 } };
	
	for (int i = 0; i < original.size(); i++)
	{
		for (int j = 0; j < original[i].size(); j++)
		{
			cout << original[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;

	vector<vector<int>> temporary { { 0, 10, 20, 15, 25, 5, 10, 10, 8, 14, 16, 11, 6, 8, 9 },
									 { 0, 0, 25, 18, 15, 6, 9, 15, 5, 10, 30, 6, 10, 15, 6, 8 },
									 { 0, 10, 10, 10, 15, 5, 18, 18, 8, 5, 13, 15, 6, 14, 1 },
									 { 0, 10, 30, 10, 25, 5, 20, 15, 9, 15, 9, 10, 10, 15, 7 },
									 { 0, 0, 9, 19, 20, 10, 30, 8, 16, 15, 9, 10, 18, 5, 9, 7 } };
	
	for (int i = 0; i < temporary.size(); i++)
	{
		for (int j = 0; j < temporary[i].size(); j++)
		{
			cout << temporary[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;

	// Declaring vector of pairs 
	vector<vector<pair<int, int>>> vect;

	// Entering values in vector of pairs
	for (int i = 0; i < vect.size(); i++)
	{
		for (int j = 0; j < vect[i].size(); j++)
		{
			vect.push_back(make_pair(original[i][j], temporary[i][j]));
		}
	}

	// Displaying the vector
	for (int i = 0; i < vect.size(); i++)
	{
		for (int j = 0; j < vect[i].size(); j++)
		{
			cout << vect[i][j].first << " "
				<< vect[i][i].second << endl;
		}
	}
	
	return 0;
}
Topic archived. No new replies allowed.