I just want to find three largest numbers of an Vec<i32> sorted in ascending order, but I have problem with the last function. I don't know how I should do this properly.
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut max_arr = vec![i32::MIN, i32::MIN, i32::MIN];
for number in array {
max_arr = Solution::update_array(max_arr, number);
}
max_arr
}
fn update_array(array: Vec<i32>, number: i32) -> Vec<i32> {
if array[2] < number {
Solution::assign_values(&array, 2, number);
} else if array[1] < number {
Solution::assign_values(&array, 1, number);
} else if array[0] < number {
Solution::assign_values(&array, 0, number);
}
array
}
fn assign_values(array: &Vec<i32>, index: i32, number: i32) {
for i in 0..index+1 {
if i == index {
array[i as usize] = number; // ERROR: `array` is a `&` reference, so the data it refers to cannot be borrowed as mutable
} else {
array[i as usize] = array[(i + 1) as usize]; // ERROR: `array` is a `&` reference, so the data it refers to cannot be borrowed as mutable
}
}
}
}
reference are by default immutable and since you are passing immutable vec reference which can be use to update the vec which is what rust is complaining.
To solve this you have to pass mutable reference which can be use to update the vec.
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut max_arr = vec![i32::MIN, i32::MIN, i32::MIN];
for number in array {
max_arr = Solution::update_array(&mut max_arr, number);
}
max_arr
}
fn update_array(array: &mut Vec<i32>, number: i32) -> Vec<i32> {
if array[2] < number {
Solution::assign_values(array, 2, number);
} else if array[1] < number {
Solution::assign_values(array, 1, number);
} else if array[0] < number {
Solution::assign_values(array, 0, number);
}
array.to_vec()
}
fn assign_values(array: &mut Vec<i32>, index: i32, number: i32) {
for i in 0..index + 1 {
if i == index {
array[i as usize] = number;
} else {
array[i as usize] = array[(i + 1) as usize];
}
}
}
}
fn main() {
println!(
"{:?}",
Solution::find_three_largest_numbers(vec![-1, 3, 15, 6, -40])
);
}
Playground
Note: One improvement I would like to suggest since you are passing mutable reference you don't need reassignment to max_arr or return from update_array method.
Here's a little solution I whipped up :) Hope it helps!
(P.S. I made sure not to use fancy iterators, just in case you're new to Rust :))
pub struct Solution;
impl Solution {
pub fn find_three_largest_numbers(array: Vec<i32>) -> Vec<i32> {
let mut largest = vec![];
for a in array.iter() {
if largest.len() < 3 {
largest.push(*a);
} else {
for i in 0..largest.len() {
if a > &largest[i]
&& !largest.contains(a) {
largest[i] = *a;
}
}
}
}
largest
}
}
fn main() {
println!("{:?}", Solution::find_three_largest_numbers(vec![-1, 3, 15, 6, -40]));
}
Related
When I try the code below for the Vec<Ev> I get a [E0308]: mismatched type error.
use std::fmt::Error;
#[derive(Debug)]
struct Ev {
semt: String,
fiyat : i32,
}
impl Ev {
fn yeni (alan: &str,fiyat: i32) -> Ev {
Self {
semt: alan.to_string(),
fiyat
}
}
}
fn dizi_yap(boyut:usize) -> Result<Vec<Ev>,Error> {
let mut evler = Vec::<Ev>::with_capacity(boyut);
evler.push(Ev::yeni("melikgazi", 210));
evler.push(Ev::yeni("kocasinan", 120));
evler.push(Ev::yeni("hacılar", 410));
evler.push(Ev::yeni("bünyan", 90));
Ok(evler)
}
fn elemani_getir(&mut dizi:Vec<Ev>, sira:usize) -> Ev {
dizi[sira]
// dizi.get(sira).expect("hata")
}
fn main() {
let mut dizi = dizi_yap(1).expect("ulasmadi");
println!("eleman: {:?}",dizi[3]);
println!("eleman: {:?}",elemani_getir(dizi, 3))
}
How can I get Vec indexed item in this example?
The syntax in you function arguments is a little off. Mutable arguments can be a little confusing, as there are two different representations. Refer to this question for a more detailed explanation.
Here is the elemali_getit function corrected:
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> &Ev {
&dizi[sira]
}
And you can call it like this:
println!("eleman: {:?}", elemani_getir(&dizi, 3))
Note that elemani_getir now returns a reference to Ev (&Ev). Returning Ev instead results in an error:
cannot move out of index of `std::vec::Vec<Ev>`
To get around this error, you can either return a reference to Ev as shown above, or return an exact duplicated of Ev my deriving the Clone trait:
#[derive(Debug, Clone)]
struct Ev {
semt: String,
fiyat: i32,
}
fn elemani_getir(mut dizi: &Vec<Ev>, sira: usize) -> Ev {
dizi[sira].clone()
}
#![feature(ptr_internals)]
use core::ptr::Unique;
struct PtrWrapper {
id: usize,
self_reference: Unique<Self>
}
impl PtrWrapper {
fn new() -> Self {
let dummy = unsafe {Unique::new_unchecked(std::ptr::null_mut::<PtrWrapper>())};
let mut ret = Self {id:0, self_reference: dummy };
let new_ptr = &mut ret as *mut Self;
debug_print(new_ptr);
ret.self_reference = Unique::new(new_ptr).unwrap();
debug_print(ret.self_reference.as_ptr());
ret
}
fn get_id(&self) -> usize {
self.id.clone()
}
}
fn main() {
println!("START");
let mut wrapper = PtrWrapper::new();
wrapper.id = 10;
let ptr = wrapper.self_reference.as_ptr();
unsafe {
(*ptr).id += 30;
println!("The next print isn't 40? Garbage bytes");
debug_print(ptr);
let tmp = &mut wrapper as *mut PtrWrapper;
(*tmp).id += 500;
println!("The next print isn't 540?");
debug_print(tmp);
}
println!("Below debug_print is proof of undefined behavior! Garbage bytes\n");
debug_print(wrapper.self_reference.as_ptr());
debug_print(&mut wrapper as *mut PtrWrapper);
debug_print_move(wrapper);
println!("Why is the assertion below false?");
assert_eq!(unsafe{(*ptr).id}, 540);
}
fn debug_print_move(mut wrapper: PtrWrapper) {
debug_print(&mut wrapper as *mut PtrWrapper);
}
fn debug_print(ptr: *mut PtrWrapper) {
println!("Address: {:p}", ptr);
println!("ID: {}\n", unsafe {(*ptr).get_id()});
}
The above code should compile fine in rust playground with a nightly selected version. Pay attention to the console outputs.
My question is: Why are the intermittent results not equal to the value I expect them to equal? In the case below, there is no multiple access simultaneously (single threaded), so there aren't any data races. There are, however, implicitly multiple mutable version of the object existing on the stack.
As expected, the memory location of the pointer changes with the tmp variable as well as when the entire object is moved into debug_print_move. It appears that using the tmp pointer works as expected (i.e., adds 500), however, the pointers which are obtained from the Unique<PtrWrapper> object seems to point to irrelevant locations in memory.
As Stargateur recommended, in order to solve this problem we need to Pin the object which needs to be self-referential. I ended up using:
pin-api = "0.2.1"
In cargo.toml instead of std::pin::pin. Next, I set this up the struct and its implementation:
#![feature(ptr_internals, pin_into_inner, optin_builtin_traits)]
// not available on rust-playground
extern crate pin_api;
use pin_api::{boxed::PinBox, marker::Unpin, mem::Pin};
///test
pub struct PtrWrapper<T>
where
T: std::fmt::Debug,
{
///tmp
pub obj: T,
/// pinned object
pub self_reference: *mut Self,
}
impl<T> !Unpin for PtrWrapper<T> where T: std::fmt::Debug {}
impl<T> PtrWrapper<T>
where
T: std::fmt::Debug,
{
///test
pub fn new(obj: T) -> Self {
Self {
obj,
self_reference: std::ptr::null_mut(),
}
}
///test
pub fn init(mut self: Pin<PtrWrapper<T>>) {
let mut this: &mut PtrWrapper<T> = unsafe { Pin::get_mut(&mut self) };
this.self_reference = this as *mut Self;
}
/// Debug print
pub fn print_obj(&self) {
println!("Obj value: {:#?}", self.obj);
}
}
Finally, the test function:
fn main2() {
unsafe {
println!("START");
let mut wrapper = PinBox::new(PtrWrapper::new(10));
wrapper.as_pin().init();
let m = wrapper.as_pin().self_reference;
(*m).obj += 30;
println!("The next print is 40");
debug_print(m);
let tmp = wrapper.as_pin().self_reference;
(*tmp).obj += 500;
println!("The next print is 540?");
debug_print(tmp);
debug_print(wrapper.self_reference);
let cpy = PinBox::get_mut(&mut wrapper);
debug_print_move(cpy);
std::mem::drop(wrapper);
println!("Works!");
assert_eq!(unsafe { (*m).obj }, 540);
}
}
fn debug_print_move<T>(mut wrapper: &mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
debug_print(&mut *wrapper as *mut PtrWrapper<T>);
}
fn debug_print<T>(ptr: *mut PtrWrapper<T>)
where
T: std::fmt::Debug,
{
println!("Address: {:p}", ptr);
unsafe { (*ptr).print_obj() };
}
On a side note, pin-api does not exist on rust playground. You could still use std::pin::Pin, however it would require further customization.
I can use resize, but it seems like overkill because I do not need to resize the vector, just modify its values. Using a new variable is not an option, since this vector is actually a field in a struct.
I guess that resize is efficient, and probably the answer to my question, but its name does not carry the meaning of resetting the values without modifying the size.
In C, I would use memset (in opposition to realloc).
Illustration of my question:
let my_vec_size = 42;
let mut my_vec = Vec::new(); // 'my_vec' will always have a size of 42
my_vec.resize(my_vec_size, false); // Set the size to 42, and all values to false
// [ ... ] piece of code where the values in 'my_vec' will be modified, checked, etc ...
// now I need to reuse my_vec.
// Possibility A -> use resize again
my_vec.resize(my_vec_size, false);
// Possibility B -> iterate on the vector to modify its values (long and laborious)
for item in my_vec.iter_mut() {
*item = false;
}
// Possibility C ?
The most efficient way in general is to reset the values themselves (aka B):
for item in &mut my_vec { *item = false; }
For booleans it is not immediately obvious, however for a String it is important to preserve the allocated buffer of each element:
for item in &mut my_vec { item.clear(); }
If discarding and recreating the elements of the Vec is cheap, such as the case of the boolean or if the elements will be overwritten anyway, then a combination of clear and resize is easier:
my_vec.clear();
my_vec.resize(my_vec_size, false);
resize by itself will not work to "reset" values:
const LEN: usize = 3;
fn main() {
let mut values = vec![false; LEN];
values[0] = true;
values.resize(LEN, false);
println!("{:?}", values); // [true, false, false]
}
Just use a for loop:
for v in &mut values {
*v = false;
}
println!("{:?}", values); // [false, false, false]
If that sight offends you, write an extension trait:
trait ResetExt<T: Copy> {
fn reset(&mut self, val: T);
}
impl<T: Copy> ResetExt<T> for [T] {
fn reset(&mut self, value: T) {
for v in self {
*v = value;
}
}
}
values.reset(false);
println!("{:?}", values); // [false, false, false]
The trait idea can be extended so that each value knows how to reset itself, if that makes sense for your situation:
trait ResetExt {
fn reset(&mut self);
}
impl<T: ResetExt> ResetExt for [T] {
fn reset(&mut self) {
for v in self {
v.reset();
}
}
}
impl ResetExt for bool {
fn reset(&mut self) {
*self = false;
}
}
impl ResetExt for String {
fn reset(&mut self) {
self.clear();
}
}
values.reset();
println!("{:?}", values); // [false, false, false]
In C, I would use memset
std::ptr::write_bytes uses memset internally, so you can (almost) precisely translate this code. An example from the Rust documentation:
let mut vec = vec![0u32; 4];
unsafe {
let vec_ptr = vec.as_mut_ptr();
ptr::write_bytes(vec_ptr, 0xfe, 2);
}
assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
I am trying to hide the type information of the impl Foo and store this information for later use. Is this even possible?
#![feature(universal_impl_trait)]
use std::any::Any;
use std::marker::PhantomData;
trait Foo {
type Item;
fn get(&self) -> Self::Item;
}
#[derive(Clone, Debug)]
struct Bar<T: Clone>(T);
impl<T: Clone> Bar<T> {
fn new(t: T) -> Self {
Bar(t)
}
}
impl<T: 'static + Clone> Foo for Bar<T> {
type Item = T;
fn get(&self) -> Self::Item {
self.0.clone()
}
}
#[derive(Clone, Debug)]
struct Baz<T: Clone, F: Clone>(T, F);
impl<T: Clone, F: Clone> Baz<T, F> {
fn new(t: T, f: F) -> Self {
Baz(t, f)
}
}
impl<T: 'static + Clone, F: 'static + Clone> Foo for Baz<T, F> {
type Item = (T, F);
fn get(&self) -> Self::Item {
(self.0.clone(), self.1.clone())
}
}
trait Get {
type Item;
fn idx(&self) -> usize;
}
struct GetBar<T> {
id: usize,
_t: PhantomData<T>,
}
impl<T> Get for GetBar<T> {
type Item = T;
fn idx(&self) -> usize {
self.id
}
}
impl<T> GetBar<T> {
fn new(id: usize) -> Self {
Self {
id,
_t: PhantomData,
}
}
}
struct GetBaz<T, F> {
id: usize,
_t: PhantomData<T>,
_f: PhantomData<F>,
}
impl<T, F> Get for GetBaz<T, F> {
type Item = T;
fn idx(&self) -> usize {
self.id
}
}
impl<T, F> GetBaz<T, F> {
fn new(id: usize) -> Self {
GetBaz {
id,
_t: PhantomData,
_f: PhantomData,
}
}
}
struct Qux {
v: Vec<Box<Any>>,
}
impl Qux {
fn new() -> Self {
Qux { v: vec![] }
}
fn add_bar<T: 'static + Clone>(&mut self, a: T) -> GetBar<T> {
self.v.push(Box::new(Bar::new(a)) as Box<Any>);
GetBar::new(self.v.len())
}
fn add_baz<T: 'static + Clone, F: 'static + Clone>(&mut self, a: T, b: F) -> GetBaz<T, F> {
self.v.push(Box::new(Baz::new(a, b)) as Box<Any>);
GetBaz::new(self.v.len())
}
fn get<T: 'static + Clone, F: 'static + Clone>(&self, val: &'static impl Get) -> Option<T> {
let node = &self.v[val.idx()];
if let Some(foo) = node.downcast_ref::<Bar<T>>() {
Some(foo.get())
} else if let Some(foo) = node.downcast_ref::<Baz<T, F>>() {
Some(foo.get().0)
} else {
None
}
}
}
fn main() {
let mut qux = Qux::new();
let a = qux.add_bar(1_i32);
let b = qux.add_bar("1");
let c = qux.add_baz(Bar::new('A'), Bar::new('B'));
assert_eq!(qux.get(&a).unwrap(), 1);
assert_eq!(qux.get(&b).unwrap(), "i");
assert_eq!(qux.get(&c).unwrap(), Bar::new('A'));
}
error[E0283]: type annotations required: cannot resolve `_: std::clone::Clone`
--> src/main.rs:121:20
|
121 | assert_eq!(qux.get(&a).unwrap(), 1);
| ^^^
Sorry for the long example but this is the best I can do.
I'm trying to reconcile the Rust static type system with dynamically dispatched trait objects. However, in many occasions I am unable to provide type annotations. What is the best way to achieve this? How can I dynamically supply type information to the trait object system?
What about qux.add_baz(GetBar::<&str>::new(1), GetBaz::<i32, i32>::new(3)); and use that type information to recursively get from qux?
Sorry for the contrived example; the real code is available on GitHub.
Calling is_null() feels a bit odd:
fn do_stuff(ptr: *const i32) -> Option<i32> {
if ptr.is_null() {
None
} else {
Some(do_transform(*ptr, 42))
}
}
As of Rust 1.9, there's a function as_ref that converts a raw pointer to an Option<&T>, and a mutable variant as_mut:
Your code would look something like
fn do_stuff(ptr: *const i32) -> Option<i32> {
let ptr = unsafe { ptr.as_ref() };
ptr.map(|x| do_transform(x, 42))
}