CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 23

Thread: Matrix input

  1. #1
    Join Date
    May 2015
    Posts
    356

    Matrix input

    Hello,

    This issue is again from my c++ practice session.
    Actually i have an input RR and CC, where RR is no of rows, CC is columns.
    And next line contains the column elements of first matrix, for each of the rows.
    Next line contains second matrix with the same info

    Now lets say input is:
    2 2
    1 2 3 4
    5 6 7 8

    The matrix are
    1 2
    3 4

    And
    5 6
    7 8

    Output should be sum of two matrix.

    6 8
    10 12

    I am trying to use the istream_iterator, which is becoming bit difficult for me, as i need to chunk out the input stream based on no of columns. Is copy_n better ?

    Code:
    #include "stdafx.h"
    #include <vector>
    #include <sstream>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
    	int CC, RR;
    
    	cin >> RR;
    
    	cin >> CC;
    
    	cin.ignore();
    
    	//vector<vector<int> > matrix(RR, vector<int>(CC));
    	vector<vector<int> > matrix1;
    	vector<vector<int> > matrix2;
    
    	string in;
    	getline(cin, in);
    	istringstream is(in);
    
    	for (int r = 0; r < RR; r++)
    	{
    		istream_iterator<int> iit(is);
    		istream_iterator<int> eos;
    		istream_iterator<int> eCol = iit + (CC -1);
    
    
    		
    
    		copy(istream_iterator<int>(is), istream_iterator<int>(), back_inserter(arr));
    
    		matrix1.push_back(arr);
    	}
    
    	for (int r = 0; r < RR; r++)
    	{
    		vector<int> arr;
    		string in;
    
    		getline(cin, in);
    		istringstream is(in);
    
    		copy(istream_iterator<int>(is), istream_iterator<int>(), back_inserter(arr));
    
    		matrix2.push_back(arr);
    	}
    
    	for (int r = 0; r < RR; r++)
    	{
    		for (int c = 0; c < CC; c++)
    		{
    			cout << matrix1[r][c] + matrix2[r][c] << " ";
    		}
    
    		cout << endl;
    	}
    
        return 0;
    }

  2. #2
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Found the solution myself (with the following hint). Sorry for the basic Q

    Code:
    #include "stdafx.h"
    #include <vector>
    #include <sstream>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    using namespace std;
    
    int main()
    {
    	int CC = 2;
    	int RR = 2;
    
    	int arr[] = { 10, 20, 30, 40 };
    	vector<vector<int>> v1(CC, vector<int>(RR));
    
    	auto inItr = begin(arr);
    	auto outItr = begin(v1);
    
    	for (int r = 0; r < RR; r++)
    	{
    		copy_n(inItr, CC, begin(*outItr));
    
    		inItr += CC;
    		outItr ++;
    	}
    
    
    	return 0;
    }

  3. #3
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    Code:
    istream_iterator<int> eCol = iit + (CC -1);
    You can't do arithmetic with an istream_iterator<>.

    If you want to read the input data like this, consider:

    Code:
    #include <vector>
    #include <sstream>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    #include <string>
    
    using namespace std;
    using Matrix = vector<vector<int>>;
    
    Matrix setmatrix(int rr, int cc)
    {
    	Matrix matrix;
    
    	string in;
    
    	getline(cin, in);
    
    	istringstream is(in);
    
    	for (int r = 0; r < rr; r++) {
    		vector<int> arr;
    		istream_iterator<int> ii(is);
    
    		copy_n(ii, cc, back_inserter(arr));
    		matrix.push_back(arr);
    	}
    
    	return matrix;
    }
    
    void displaymatrix(const Matrix& m)
    {
    	for (const auto& r : m) {
    		for (const auto& c : r)
    			std::cout << c << "  ";
    
    		std::cout << '\n';
    	}
    
    	std::cout << '\n';
    }
    
    int main()
    {
    	int CC = 0, RR = 0;
    
    	cin >> RR >> CC;
    	cin.ignore(1000, '\n');
    
    	const Matrix matrix1 = setmatrix(RR, CC);
    	const Matrix matrix2 = setmatrix(RR, CC);
    
    	displaymatrix(matrix1);
    	displaymatrix(matrix2);
    
    	for (int r = 0; r < RR; r++) {
    		for (int c = 0; c < CC; c++)
    			cout << matrix1[r][c] + matrix2[r][c] << "  ";
    
    		cout << '\n';
    	}
    }
    giving:

    Code:
    2 2
    1 2 3 4
    5 6 7 8
    1  2
    3  4
    
    5  6
    7  8
    
    6  8
    10  12
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  4. #4
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Thankyou very much kaud..Very helpful.

    Btw,
    In the setmatrix function:
    Code:
    	for (int r = 0; r < rr; r++) {
    		vector<int> arr;
    		istream_iterator<int> ii(is);
    
    		copy_n(ii, cc, back_inserter(arr));
    		matrix.push_back(arr);
    	}
    I am not getting the red line. I was thinking i need to increment ii iterator to point to next row.. because the stream "is" is same after copy_n operation.. only iterator needs to be incremented.

    I would have put , istream_iterator<int> ii(is); outside for loop. and increment the ii within loop...

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    I would have put , istream_iterator<int> ii(is); outside for loop. and increment the ii within loop...
    Note that you can only use ++ on istream_iterator. You can't increment by a number.

    If you put istream_iterator<int> ii(is) outside of the loop and increment within the loop, you don't get the correct result - try it.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  6. #6
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Thanks a lot kaud. Yes ofcourse, your program gives correct output .

    But what i am trying to find out is, what the copy operation does to stringstream "is". I was thinking, copy copies and increments just the iterator and "is" remains unaltered. But looks like i.e not the case.

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    When you extract from a string stream, the stream gets incremented.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  8. #8
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Sorry may be i was not clear, in my question earlier.

    Basically, i tried to write two inputs , one with vetor of ints and another string stream to elaborate the doubt i am having . Sorry it may be bit minor , but just wanted to put it across

    Code:
    int main() {
    
    	vector<int> in{125, 320, 512, 750, 333};
    	
    	vector<int> out;
    
    	auto it = begin(in);
    
    	copy_n(it, 1, back_inserter(out));
    
           // At this point the "in" still contains the original {125, 320, 512, 750, 333}
    	return 0;
    
    }
    But here, in the following code :

    Code:
    int main() {
    
    	std::string stringvalues = "125 320 512 750 333";
    	std::istringstream iss(stringvalues);
    
    	vector<int> out;
    	istream_iterator<int> ii(is);
    	
    	copy_n(is, 1, back_inserter(out));
    
            // At this point iss contains the "320 512 750 333"
    	// eventhough we accessed the iss through the iterator
            // copy_n accesses the >> operator of original vector !! ( for me it looks wrong). 
            // Iterator access shouldnot alter the source 
    	for (int n = 0; n<5; n++)
    	{
    		int val;
    		iss >> val;
    		std::cout << val  << '\n';
    	}
    
    	return 0;
    }

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    Input iterator access doesn't 'alter' the source data. But the part to which it points changes. Think of a string stream as a file. When reading a file, the contents of the file doesn't change, but the current position within the file changes when reading. Have a look at and experiment with tellg() for an istringstream.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  10. #10
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Thankyou very much kaud for the help and your patience . Very helpful .

  11. #11
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Hi kaud,

    I tried to modify your program a bit, just trying to add a new function, addMatrix. This is just for my own study purpose, so not URGENT at all. I am sorry, for asking the basic qs, so please reply to me with low priority

    So i changed the following, and i am getting debug assertion, saying, "vector iterators incompatible" with transform function call. (May be passing row and column sizes is easier option)
    Code:
    #include "stdafx.h"
    #include <vector>
    #include <sstream>
    #include <algorithm>
    #include <iostream>
    #include <iterator>
    
    
    using namespace std;
    using Matrix = vector<vector<int>>;
    
    Matrix setmatrix(const int RR, const int CC)
    {
    	Matrix mat;
    	string in;
    	std::istringstream iss(in);
    	vector<int> vec;
    
    	getline(cin, in);
    
    	for (int r=0; r< RR; r++)
    	{
    		vector<int> vec;
    		copy_n(istream_iterator<int>(iss), CC, back_inserter(vec));
    
    		mat.push_back(vec);
    	}
    
    	return mat;
    }
    
    Matrix addMatrix(const Matrix & mat1, const Matrix & mat2)
    {
    	Matrix mat;
    
    	{
    		for (auto r1 = begin(mat1), r2 = begin(mat2); r1 != end(mat1); r1++, r2++)
    		{
    			vector<int> r;
    			std::transform(begin(*r1), begin(*r2), end(*r1), back_inserter(mat), [&r](int i, int j) 
    			{
    				r.push_back(i+j);
    				return r;
    
    			});
    
    		}
    	}
    
    	return mat;
    }
    void dispaymatrix(const Matrix & mat)
    {
    	for (auto r : mat)
    	{
    		for (auto c : r)
    		{
    			cout << c;
    		}
    
    		cout << "\n";
    	}
    }
    
    int main()
    {
    	int CC(0), RR(0), M(0);
    
    	cin >> M;
    
    	for (int m = 0; m < M; m++)
    	{
    
    		cin >> RR >> CC;
    
    		cin.ignore();
    
    		const Matrix mat1 = setmatrix(RR, CC);
    
    		const Matrix mat2 = setmatrix(RR, CC);
    
    		Matrix mat3 = addMatrix(mat1, mat2);
    
    		dispaymatrix(mat3);
    	}
    
    	return 0;
    }

  12. #12
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    What makes you think that i, j are ints?

    Transform calls binary_op using each of the elements in the range [first1,last1) as first argument, and the respective argument in the range that begins at first2 as second argument.
    As mat1 and mat2 are of type vector<vector<int>>, aren't i and j of type vector<int> ?
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  13. #13
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Thankyou very much kaud for looking into this and giving suggestions

    mat1 is of type vector<vector<int>>.


    But *r1 is of type vector<int>, I was hoping that the transform takes each column of type (vector<int>) and adds with r2.

    Something like :

    vector<int> numbers1 = {1, 5, 42, 7, 8};
    vector<int> numbers2 = {10, 7, 4, 2, 2};
    vector<int> results;
    std::transform(numbers1.begin(), numbers1.end(),
    numbers2.begin(),
    std::back_inserter(results),
    [](int i, int j) {return i+j;});

    There is one more correction to my addMatrix (but still getting same error). Wil check again,
    Code:
    Matrix addMatrix(const Matrix & mat1, const Matrix & mat2)
    {
    	Matrix mat;
    
    	{
    		for (auto r1 = begin(mat1), r2 = begin(mat2); r1 != end(mat1); r1++, r2++)
    		{
    			vector<int> r;
    			std::transform(begin(*r1), begin(*r2), end(*r1), back_inserter(r), [](int i, int j) 
    			{
    				return(i+j);
    
    			});
    
    			mat.push_back(r);
    
    		}
    	}
    
    	return mat;
    }
    Btw, it looks like *r1 is const_iterator, because if i explicitly assign iterator type instead of auto:
    const vector<int>::iterator it = begin(*r1); does not like, but const vector<int>::const_iterator it = begin(*r1); is ok !
    Last edited by pdk5; November 6th, 2020 at 05:15 AM.

  14. #14
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,320

    Re: Matrix input

    OK. As mat1, mat2 are declared const, you need to use cbegin/cend rather than begin/end. This then compiles.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2019 (16.8.2)

  15. #15
    Join Date
    May 2015
    Posts
    356

    Re: Matrix input

    Thankyou kaud, yes now it compiles, But still getting same debug assertion, saying, "vector iterators incompatible" with transform function call.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)