How to rank elements of an integer vector based on their sorted order in Rust

1 Answer

0 votes
/*
    Ranking elements of an integer vector based on sorted order in Rust
    -------------------------------------------------------------------

    Ranking rules:
    - Lowest value gets rank 1
    - Equal values share the same rank
    - Rank increases only when encountering a new unique value
*/

use std::collections::HashMap;

// ------------------------------------------------------------
// Function 1: Print the vector
// ------------------------------------------------------------
fn print_vec(vec: &Vec<i32>) {
    println!("Vector: {:?}", vec);
}

// ------------------------------------------------------------
// Function 2: Create a copy of the vector
// ------------------------------------------------------------
fn copy_vec(vec: &Vec<i32>) -> Vec<i32> {
    vec.clone()
}

// ------------------------------------------------------------
// Function 3: Sort the vector copy
// ------------------------------------------------------------
fn sort_vec(vec_copy: &mut Vec<i32>) {
    vec_copy.sort();
}

// ------------------------------------------------------------
// Function 4: Build a map of value → rank
// ------------------------------------------------------------
fn build_rank_map(sorted_vec: &Vec<i32>) -> HashMap<i32, i32> {
    let mut map: HashMap<i32, i32> = HashMap::new();

    if sorted_vec.is_empty() {
        return map;
    }

    let mut rank: i32 = 1;
    let mut previous: i32 = sorted_vec[0];

    map.insert(previous, rank);

    for i in 1..sorted_vec.len() {
        let current: i32 = sorted_vec[i];

        if current != previous {
            rank += 1;
        }

        map.insert(current, rank);
        previous = current;
    }

    map
}

// ------------------------------------------------------------
// Function 5: Apply ranks to original vector order
// ------------------------------------------------------------
fn apply_ranks(original: &Vec<i32>, rank_map: &HashMap<i32, i32>) -> Vec<i32> {
    let mut ranked: Vec<i32> = Vec::with_capacity(original.len());

    for value in original {
        ranked.push(*rank_map.get(value).unwrap());
    }

    ranked
}

// ------------------------------------------------------------
// Main ranking function
// ------------------------------------------------------------
fn rank_vec(vec: &Vec<i32>) {
    print_vec(vec);

    if vec.is_empty() {
        return;
    }

    let mut vec_copy: Vec<i32> = copy_vec(vec);
    sort_vec(&mut vec_copy);

    let rank_map: HashMap<i32, i32> = build_rank_map(&vec_copy);

    let ranked: Vec<i32> = apply_ranks(vec, &rank_map);

    println!("Rank:  {:?}", ranked);
}

// ------------------------------------------------------------
// MAIN PROGRAM
// ------------------------------------------------------------
fn main() {
    let vec: Vec<i32> = vec![33, 99, 10, 25, 47, 11, 77];

    rank_vec(&vec);
}



/*
run:

Vector: [33, 99, 10, 25, 47, 11, 77]
Rank:  [4, 7, 1, 3, 5, 2, 6]

*/

 



answered 1 day ago by avibootz

Related questions

...