Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

In rust. Part A: Two-Dimensional, Polymorphic Arrays The Rust standard library provides the Vec, which implements polymorphic one-dimensional arrays. Now, a two-dimensional analog of a

In rust.

Part A: Two-Dimensional, Polymorphic Arrays

The Rust standard library provides the Vec, which implements polymorphic one-dimensional arrays. Now, a two-dimensional analog of a vector is usually referred to as a matrix but the term matrix carries the connotation of containing numbers and being used for linear algebra. Since the purpose here will be to support images (2-dimensional collections of pixels), we will use the term array. For this part of the assignment, youll adapt the vector abstraction to support two-dimensional arrays. Your adaptation will be called Array2 and should be

polymorphic, just as Vec is polymorphic. Your adaptation should include the following changes when compared to a Vec:

Instead of a length, an Array2 will have a width and a height.

Instead of being identified by a single index, an element of an Array2 will be identified by two indices: the column or x index measures the distance between the element and the left edge of the array, while the row or y index measures the distance between the element and the top row of the

array. Thus the top left element is always indexed by the pair (0,0).

You will want to support several kinds of iterators on your array. In par- ticular, you must support row-major and column-major iteration. We suggest you name these functions iter_row_major and iter_col_major,

respectively. Row-major refers to visiting every element of the first row in order by column, followed by every element of the second row, and so forth. Column-major refers to visiting every element of the first (left-most) column, followed by every element of the second column, and so forth.

Recall that an Iterator implementation has a next() function, as well as an Item defined.

An Item need not just be the T element contained within your array2; it could be a data structure with more information about where that T lives in your array2, for instance.

A common lightweight data structure to use here is a tuple, whose elements can be accessed by index rather than name.

Hints:

The key to this problem is to set up an implementation in which the elements of your two-dimensional array are in one-to-one correspondence with elements of one or more one-dimensional Vecs. The key question to answer is:

How do you relate each element in a two-dimensional array to a corresponding element in some one-dimensional Vec?

If you have a precise answer to this question, the code is pretty easy to get right.

Dont worry about performance; aim for simplicity. If you feel compelled to worry about performance, you may make simple code improvements pro- vided you justify them. Dont try anything radical; premature optimization is the root of much evil.

Think carefully about how the next() function for the Iterator imple- mentation should behave.

Depending on your choice of underlying representation, one map function might be blindingly simple, while the other might be more work.

Dont worry about the macros that can be used for literal vector construc- 2

tion. You might use those macros in your constructors, but you do not need to implement a macro to create an Array2.

You will need some reasonable constructors:

Something like a from_row_major constructor might be useful; it might take the elements of an array in row-major order as the name implies.

You might also want a from_col_major constructor.

You might want a blank slate constructor that allows for a single value to be copied to each element. Note that since this is a polymor- phic datatype, you dont know what this element will be. Having it be the integer value 0 does not make sense. Consider the following

macro usage: let data = vec![val; width * height];

You do not need to worry about providing element access using square

bracket notation

you probably do want to provide a function that allows access to an element by a pair of coordinates

You will want to create this project using cargos lib mode:

cargo new --lib array2 move and Box:

You may need to use the move keyword to implement your iterators. This keyword is used when a function needs to take ownership of a variable that was originally defined outside of the scope of that function.

Lets work through an example:

pub fn is_too_big_builder(threshold: u32) -> Box bool> { Box::new(move |value: u32| value > threshold)

}

At first glance, this seems like a complicated function. Lets break down the signature:

The function is_too_big_builder takes a single argument, threshold.

It returns a Box of a new function.

That returned function takes a u32 and returns a bool.

The returned function lives on the heap, and we get a Box, i.e. a pointer,

to it. Lets move on to the body:

Box::new(...) creates a new pointer to something living on the heap. Whatever lives on the heap has to be passed to Box::new.

|value: u32| value > threshold is a closure, i.e. an anonymous func- tion, that takes one value of type u32 and returns whether or not value is greater than threshold (a boolean value).

Note the move keyword: thresholdwasoriginallydefinedinthesignatureforis_too_big_builder,

i.e. before the closure was created. The closure uses threshold directly, i.e. by value instead of by refer-

ence. Therefore, the closure needs to take ownership of threshold. In other words, the ownership of threshold needs to be moved from

the builder to the closure. Heres an example of the builder being used:

#[test] fn test_builder() {

let is_over_nine_thousand = is_too_big_builder(9_000);

assert!(is_over_nine_thousand(12_000)); // True

assert!(is_over_nine_thousand(6_000)); // False }

How to construct an Array2

Unlike in C, you cannot create a data structure with allocated but unini- tialized elements

Ok,thisisabitofalie You can use MaybeUninit in unsafe Rust: https://doc.rust-

lang.org/nomicon/unchecked-uninit.html But this is too advanced for what we want to do right now

At a minimum, you want a from_row_major() constructor that takes a vector of elements in row-major order, and a set of dimensions

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

More Books

Students also viewed these Databases questions