Coordinates for elements in an multi-dimensional Array

Hello,

I'm pretty new to the C++, and I've been given an assignment to create a square 2D array (I'm translating it literally, I'm sorry, it's not in English, if it's not clear, there will be an image later in the post) and to find the smallest element that is below the main diagonal, and declare the coordinates of the element..

Something along the lines of this (ignore the orange numbers) http://imgur.com/vmlk7kn

The numbers circled in green are the ones to be used by the program when determining the smallest element, which is, in that case 4.


My code is an absolute mess and I am very lost as to how to make the program understand which digits to take from the array.

I would really love some advice/help/answers, whatever to at least get me on track to solve this. Thank you very much.

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
#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
double x[100][100]={};
int a, koorX, koorY;
int min;

cout << "Size of the array:\n";
cin >> a;

cout << "Elements of the array:\n" ;
for(int z=0; z<a; z++){
    for(int y=0; y<a; y++){
cin >> x[z][y];

min=x[z][y];
if(x[z][y]<min)
    {
    min=x[z][y];

    koorY = ; 
    koorX = ;

    }
    }
}
    return 0;
    }

Last edited on
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
#include <iostream>
#include <vector>

int main()
{
    std::cout << "Enter size of the array.\n> ";

    std::size_t dim;
    std::cin >> dim;

    std::vector<std::vector<double>> matrix(dim, std::vector<double>(dim));

    std::cout << "Enter the elements of the array.\n> ";
    for (std::size_t row = 0; row < dim; ++row)
        for (std::size_t col = 0; col < dim; ++col)
            std::cin >> matrix[row][col];

    std::cout << "The elements we're concerned with:\n";

    for (std::size_t row = 0; row < dim; ++row) {
        for (std::size_t col = 0; col < row; ++col)
            std::cout << matrix[row][col] << ' ';
        std::cout << '\n';
    }
}


http://ideone.com/UzGn98
We've not been through to vectors so I guess I'll read up on it. Thank you for the reply!
Last edited on
There are different ways of doing this - it depends on what the assignment is asking for.
This is how I might do it:

Start with a two-dimensional array of integers.
This array will represent a square, which means the two sides will always be equal in length. For this reason, we only really need one constant to represent the dimensions of our square (as opposed to using 'width' and 'height').
1
2
3
4
5
6
const int scale = 3;
	int numbers[scale][scale] = {
		1, 2, 3,
		4, 5, 6,
		7, 8, 9
	};


Next, create a set of integers. A set is an associative container (it's kind of like a map, but it only has a key instead of a key-value pair). We'll be using this set later to keep track of which numbers can actually be the minimum number (in my example, the set will contain the numbers 4, 7 and 8). What's nice about using a set is that each of it's elements must be unique, and its elements are internally ordered from lowest to greatest by default.

std::set<int> set;

Now that we have the set, we can populate it with numbers we're interested in.
We have a for-loop that iterates through each of the rows, and a nested for-loop that iterates through elements of each row.

1
2
3
4
5
for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < y; ++x) {
			set.insert(numbers[y][x]);
		}
	}


Notice how the second for-loop only executes while (x < y). With each iteration of the outer for-loop, 'y' is incremented by one, which has the following effect:

y = 0
x = 0
(x < y) is false - nothing is inserted to the set.

y = 1
x = 0
(x < y) is true - insert 'numbers[1][0]', which is 4, into the set.

y = 1
x = 1
(x < y) is false.

y = 2
x = 0
(x < y) is true - insert 'numbers[2][0]', which is 7, into the set.

y = 2
x = 1
(x < y) is true - insert 'numbers[2][1]', which is 8, into the set.

y = 2
x = 2
(x < y) is false.


The set now contains 4, 7 and 8. These three numbers will also be ordered from lowest (4) to greatest (8). Therefore, the smallest number in that region of the square will always be the first element in the set. We can retrieve the first element of the set like so:

std::cout << "The smallest number is " << *set.begin() << "." << std::endl;

The final program might look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <set>

int main() {

	const int scale = 3;
	int numbers[scale][scale] = {
		1, 2, 3,
		4, 5, 6,
		7, 8, 9
	};

	std::set<int> set;

	for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < y; ++x) {
			set.insert(numbers[y][x]);
		}
	}

	std::cout << "The smallest number is " << *set.begin() << "." << std::endl;
	return 0;
}
Last edited on
Thanks, xismn, this is very informative. I wanted to ask, since I am required to have user input for the scale, I can just freely add it?

Also, due to my complete incompetence, I have failed to specify: I need to find the coordinates of the element, not only which element is the smallest, which I still don't understand how to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <set>


int main()
{
  int scale;
int numbers [scale][scale]={};


std::set<int> set;

    std::cout<<"Declare the scale:\n";
    std::cin>>scale;
    
    for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < y; ++x) {
			set.insert(numbers[y][x]);
		}
	}

	std::cout << "The smallest number is: " << *set.begin() << "." << std::endl;
	return 0;
}


I have tried running the code together with the additions I've made, and it just crashes... Darn.

I apologize if I've made some mistakes regarding the std:: expressions as we have not been taught to use those and I'm just winging it from what I've observed.

Another side note:
Is there any difference to using ++x or x++ in this instance?


I have realized that I may have completely missed the point in your explanation.
Last edited on
I have fiddled around with the code and I have actually made it work, but it outputs 0 every time? Have I f***ed up the order of the for cycles or should I be aware of something else?

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
#include <iostream>
#include <set>


int main()
{
    int scale;
    int numbers[scale][scale];


std::set<int> set;

    std::cout<<"Declare the scale:\n";
    std::cin>>scale;

    std::cout<<"Put in the elements:\n";
    for(int g=0; g<scale; g++){
        for(int h=0; h<scale; h++){
std::cin >> numbers[scale][scale];

        }
    }
    
   for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < y; ++x) {
			set.insert(numbers[y][x]);
		}
	}
	std::cout << "The smallest number is: " << *set.begin() << "." << std::endl;
	return 0;
}


Still not aware of how to interpret ++y and ++x and why they are used.

It's 4:34 AM where I am so I will be responding only in the morning. Thank you!
Last edited on
rviens,

Sorry for the late reply. I've modified my code some, and added comments:

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
#include <iostream>
#include <iomanip>
#include <map>

//This function converts two-dimensional coordinates to an index.
int to_index(int x, int y, int scale) {
	return (x + (y * scale));
}

int main() {

	int scale = 0;

	while (scale <= 0) {
		//If the user enters '0' or less for the scale, keep prompting for a proper scale.
		std::cout << "Enter the scale: ";
		std::cin >> scale;
		std::cin.ignore();
	}
	std::cout << std::endl;

	//'total_size' is the total number of elements in our array.
	const int total_size = (scale * scale);

	/*
	'numbers' is an integer pointer. This will be our equivalent of the two-dimensional array, and we can access it similarly.
	The 'new' operator returns a pointer to a newly allocated array of 'total_size'-number of integers in heap memory.
	You can think of this as a simple one-dimensional array, but we're pretending it's two-dimensional.
	*/
	int* numbers = new int[total_size] {};

	//We enter this for-loop to initialize each element in our 'numbers' array.
	for (int i = 0; i < total_size; ++i) {
		numbers[i] = (i + 1);
	}

	//These two for-loops print our square.
	for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < scale; ++x) {
			const int index = to_index(x, y, scale);
			std::cout << std::setw(3) << numbers[index];
		}
		std::cout << std::endl << std::endl;
	}

	/*
	Instead of a set, I've elected to use a map.
	A map is an associative container.
	The first template parameter is the 'key', by which we can access elements in the map (think of it like the index).
	The second template parameter is a given key's associated value.
	
	In our example, the key will be the number in our region, and the value will be a pair of integers that represents the x-y coordinates where that number sits in our square.
	
	*/
	std::map<int, std::pair<int, int>> map_region;

	//Here are the for-loops that insert the numbers from our desired region of the square into the map.
	for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < y; ++x) {
			const int index = to_index(x, y, scale);
			map_region[numbers[index]] = std::make_pair(x, y);
		}
	}

	//The smallest number in the region will always be the first element in the map.
	int smallest_number = map_region.begin()->first;
	int pos_x = map_region.begin()->second.first;
	int pos_y = map_region.begin()->second.second;

	std::cout << std::endl << "The smallest number in our region is " << smallest_number << " located at (" << pos_x << ", " << pos_y << ")." << std::endl;

	//Anytime we use 'new', we need to 'delete' when we're done with our memory.
	delete[] numbers;
	std::cin.ignore();
	return 0;
}


As far as 'x++' vs '++x' is concerned, in a basic for-loop it doesn't really make a difference. There are special circumstances where the distinction is important. If you're interested look up "C++ prefix vs postfix".
Last edited on
Thank you for the reply, xismn!
I have ran your code, and I have realized that there is no user input, so it always draws a 1, 2, 3... so on array.

1
2
3
for (int i = 0; i < total_size; ++i) {
		numbers[i] = (i + 1);
	}


Is it possible to replace this part with user input (this is very important for my assignment). I've noticed, that once I would put in user input and make the array random, this part:

1
2
3
int smallest_number = map_region.begin()->first;
	int pos_x = map_region.begin()->second.first;
	int pos_y = map_region.begin()->second.second;


would also be null and void.
Last edited on
Is it possible to replace this part with user input


Something like this maybe?
1
2
3
4
5
6
7
8
9
for (int y = 0; y < scale; ++y) {
		for (int x = 0; x < scale; ++x) {
			const int index = to_index(x, y, scale);
			std::cout << "Enter value for location (" << x << ", " << y << "): ";
			std::cin >> numbers[index];
			std::cin.ignore();
		}
	}
	std::cout << std::endl;


I've noticed, that once I would put in user input and make the array random, this part: ... would also be null and void.

It's not, though. The map's first element will be the lowest, whether the numbers were entered by someone or not.
We've not been through to vectors so I guess I'll read up on it. Thank you for the reply!

Past line 11 in the code I posted, it doesn't matter that vectors are in use. That code works the same for a multi-dimensional array or a vector of vectors.

Mostly equivalent:
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
#include <iostream>

int main()
{
    std::cout << "Enter size of the array.\n> ";

    std::size_t dim;
    std::cin >> dim;

    double matrix[100][100];

    // std::vector<std::vector<double>> matrix(dim, std::vector<double>(dim));

    std::cout << "Enter the elements of the array.\n> ";
    for (std::size_t row = 0; row < dim; ++row)
        for (std::size_t col = 0; col < dim; ++col)
            std::cin >> matrix[row][col];

    std::cout << "The elements we're concerned with:\n";

    for (std::size_t row = 0; row < dim; ++row) {
        for (std::size_t col = 0; col < row; ++col)
            std::cout << matrix[row][col] << ' ';
        std::cout << '\n';
    }
}
xismn,

thank you very much for the help! You basically did the assignment for me, however I've learned a lot (did research on maps and sets). The most important part is to follow the logic behind every line and it's really nice to have an experienced person write code for me to analyze!

Hope you have fantastic holidays!


EDIT:
cire,

I'm sorry, I didn't notice your reply in time! Thank you for the input!
Last edited on
Topic archived. No new replies allowed.