Программирование/Примеры программ на языке программирования Rust
Внешний вид
Вычисление факториала рекурсивным и итеративным методами
[править]// Ветви условия в данной функции демонстрируют необязательный вариант
// неявного возврата значений, что может быть удобно при использовании
// "функционального" стиля. В отличие от C++ и других родственных языков,
// в Rust if - это выражение, возвращающее значение, а не просто оператор.
fn fac_recur(n: i32) -> i32 {
if n <= 1 {
1
} else {
n * fac_recur(n-1)
}
}
fn fac_iter(n: i32) -> i32 {
// Переменные объявляются с ключевым словом "let", по умолчанию
// не изменяемые. Если нужна их изменяемость, добавляется ключевое
// слово 'mut'.
let mut i = 1;
let mut result = 1;
while i <= n {
result *= i;
i += 1;
}
return result; // Пример явно возвращаемого значения.
}
fn fac_lambda(n: i32) -> i32 {
// Итераторы включают множество методов трансформации.
// "|accum, x|" - это определение анонимной функции.
// Оптимизации компиляции преобразуют эту функцию
// в нечто, похожее на итеративный вариант.
(1..=n).fold(1, |accum, x| accum * x)
}
fn fac_iter1(n: i32) -> i32 {
(1..=n).product()
}
fn main() {
let num = 10;
println!("Recursive result: {}", fac_recur(num));
println!("Iterative result: {}", fac_iter(num));
println!("Iterative result: {}", fac_iter1(num));
println!("Lambda result: {}", fac_lambda(num));
}
Вычисление чисел Фибоначчи рекурсивным и итеративным методами
[править]/// Классическая рекурсивная версия
/// без хвостовой рекурсии
fn fib_recursive(n: u64) -> u64 {
match n {
0 | 1 => n,
n => fib_recursive(n - 1) + fib_recursive(n - 2),
}
}
/// версия с хвостовой рекурсией
fn fib_tail_recursive(n: u64) -> u64 {
fn in_fib(n: u64, current: u64, next: u64) -> u64 {
match n {
0 => current,
n => in_fib(n - 1, next, current + next),
}
}
in_fib(n, 0, 1)
}
/// итеративная версия
fn fib_iterative(n: u64) -> u64 {
let (mut cur, mut next) = (0u64, 1u64);
for _ in 0u64..n {
let tmp = cur + next;
cur = next;
next = tmp;
}
cur
}
fn main() {
let fns = vec![(fib_recursive as fn(u64) -> u64, "recursive"),
(fib_tail_recursive as fn(u64) -> u64, "tail recursive"),
(fib_iterative as fn(u64) -> u64, "iterative")];
for (f, desc) in fns {
let r = (0u64..10).map(f).collect::<Vec<u64>>();
println!("{} implementation:\n{:?}\n", desc, r);
}
}
Демонстрация возможностей параллельных вычислений в Rust
[править]use std::thread;
// Функция создаёт 10 "задач", которые выполняются параллельно.
// Чтобы убедиться в параллельности, запустите программу несколько раз,
// и обратите внимание на непостоянный порядок вывода результатов.
fn main() {
// Эта строка неизменяемая, поэтому может безопасно использоваться
// из нескольких задач.
let greeting = "Привет";
let mut threads = Vec::new();
// Цикл for работает с любым типом, реализующим
// интерфейс (trait) Iterator.
for num in 0..10 {
threads.push(thread::spawn(move || {
// println! - это статический макрос, выполняющий форматирование
// строки и её вывод. Макросы структурные (как в Scheme), а не
// текстовые (как в Си).
println!("{} из потока номер {}", greeting, num);
}));
}
for thread in threads {
let res = thread.join();
if let Err(_) = res {
println!("Произошла ошибка!");
}
}
}
Поиск подстроки в текстовом файле
[править]// поддержка метода lines()
use std::io::BufRead;
fn main() {
// получает аргументы командной строки
let pattern = std::env::args().nth(1).unwrap();
let file_name = std::env::args().nth(2).unwrap();
// открывает файл, разворачивает Result
let file = std::fs::File::open(file_name).unwrap();
let buffer = std::io::BufReader::new(file);
// читает строку из файла
for line_result in buffer.lines() {
let line = line_result.unwrap();
// ищет подстроку в строке
if line.contains(&pattern) {
println!("{}", line);
}
}
}
Факторизация чисел
[править]//функция факторизации чисел без знака
fn factorization_unsigned(mut a:u64)->Vec<u64>
{
let mut arr:Vec<u64>=Vec::with_capacity(2);
let mut g:u64=a/2;
let mut i:u64=2u64;
arr.push(1);
while i<=g
{
g=a/i;
while a%i==0
{
arr.push(i);
a/=i;
}
i+=1;
}
if a != 1
{
arr.push(a);
}
return arr;
}
//функция факторизации чисел со знаком
fn factorization_signed(mut a:i64)->Vec<i64>
{
let mut arr:Vec<i64>=Vec::with_capacity(2);
if a<0
{
arr.push(-1);
a = -a;
}
else
{
arr.push(1);
}
let mut g:i64=a/2;
let mut i:i64=2i64;
while i<=g
{
g=a/i;
while a%i==0
{
arr.push(i);
a/=i;
}
i+=1;
}
if a != 1
{
arr.push(a);
}
return arr;
}
fn main()
{
let num1=-9;
{
let arr=factorization_signed(num1);
print!("factorization_signed({}) = [", num1);
for _i in &arr[..arr.len()-1]
{
print!("{}, ", _i);
}
println!("{}]", arr[arr.len()-1]);
}
let num2=9;
{
let arr=factorization_unsigned(num2);
print!("factorization_unsigned({}) = [", num2);
for _i in &arr[..arr.len()-1]
{
print!("{}, ", _i);
}
println!("{}]", arr[arr.len()-1]);
}
}
Поиск совершенных чисел
[править]use std::time::Instant;
static mut TIME:Option<Instant>=None;
#[allow(non_camel_case_types)]
type perfnum_numb_type = u32;
fn perfnum(x : perfnum_numb_type)-> Vec<perfnum_numb_type>
{
let mut arr=Vec::new();
let width={(x).to_string().len()+1};
let mut i0=1;
while i0<=x
{
let mut acc : perfnum_numb_type=1;
let mut i1=2;
while i1<=i0/2
{
if i0%i1==0
{
acc+=i1;
}
i1+=1;
}
if acc==i0
{
unsafe
{
if let Some(t) = TIME
{
let time=Instant::now().duration_since(t);
arr.push(i0);
println!("number: {:<width$} time: {:?}", format!("{},", i0), time, width=width);
}
}
}
i0+=1;
}
return arr;
}
fn perfnum1(n : perfnum_numb_type) -> Vec<perfnum_numb_type>
{
let mut arr=Vec::new();
let width={(x).to_string().len()+1};
for item in (1..=n).filter(|x| (2..=*x/2).filter(|n| x%n==0).sum::<perfnum_numb_type>()+1==*x)
{
unsafe
{
if let Some(t) = TIME
{
let time=Instant::now().duration_since(t);
arr.push(item);
println!("number: {:<width$} time: {:?}", format!("{},", item), time, width=width);
}
}
}
arr
}
fn main()
{
unsafe{TIME=Some(Instant::now());}
/*let arr=*/perfnum(8128);
let time_end=Instant::now();
unsafe
{
if let Some(t) = TIME
{
let time=time_end.duration_since(t);
println!("time: {:?}", time);
}
}
unsafe{TIME=Some(Instant::now());}
/*let arr=*/perfnum1(8128);
let time_end=Instant::now();
unsafe
{
if let Some(t) = TIME
{
let time=time_end.duration_since(t);
println!("time: {:?}", time);
}
}
}
#[allow(non_camel_case_types)]
type tupe=i64;
fn bubble_sort(a:&mut Vec<tupe>)
{
if a.len()<2 {return ();}
loop
{
let mut flag = true;
for _i in 0..a.len()-1
{
if a[_i]>a[_i+1]
{
let temp = a[_i];
a[_i] = a[_i+1];
a[_i+1] = temp;
flag = false;
}
}
if flag
{
break;
}
}
}
fn main()
{
let mut list = vec![10,29,14,4,35,6];
println!("{:?}", list);
bubble_sort(&mut list);
println!("{:?}", list);
}
#[allow(non_camel_case_types)]
type tupe=i64;
fn quicksort(a:&mut Vec<tupe>)
{
if a.len()<=1
{return ();}
let mut amin=Vec::new();
let mut amax=Vec::new();
for _i in &a[1..]
{
if *_i>a[0]
{
amax.push(*_i);
}
else
{
amin.push(*_i);
}
}
quicksort(&mut amin);
quicksort(&mut amax);
amin.push(a[0]);
amin.extend(amax);
for (_num, _i) in amin.iter().enumerate()
{
a[_num]=*_i;
}
}
fn quicksort1(s_arr:&mut [tupe])
{
if s_arr.len() < 2 {
return ();
}
let last = s_arr.len()-1;
if 0 < last
{
let mut left = 0;
let mut right = last;
let middle = s_arr[ last / 2];
loop
{
while s_arr[left] < middle {left+=1};
while s_arr[right] > middle {right-=1};
if left < right
{
let tmp = s_arr[left];
s_arr[left] = s_arr[right];
s_arr[right] = tmp;
left+=1;
right-=1;
}
else {break;}
}
right-=1;
left+=1;
quicksort1(&mut s_arr[0..=right]);
quicksort1(&mut s_arr[left..=last]);
}
}
fn main()
{
let listfir = vec![10,29,14,4,35,6];
let mut list = listfir.clone();
println!("{:?}", list);
quicksort(&mut list);
println!("{:?}", list);
let mut list = listfir.clone();
println!("{:?}", list);
quicksort1(&mut list[..]);
println!("{:?}", list);
}
Нахождение наибольшего общего делителя алгоритмом Евклида и наименьшего общего кратного, двух и более чисел
[править]//Наибольший общий делитель
fn euclidean_algorithm(arr: &mut [i64]) -> Option<i64>
{
let mut a_len = arr.len();
let mut temp : i64;
while a_len > 1
{
let len = a_len-1;
temp = arr[len-1] % arr[len];
*arr[len-1]= *arr[len];
*arr[len] = temp;
if *arr[len] == 0
{
a_len -= 1;
}
}
return Some(arr[0]);
}
fn euclidean_algorithm1(arr: &[i64]) -> std::option::Option<i64>
{
let mut arr : Vec<i64> = arr.to_vec();
let mut temp : i64;
while arr.len() > 1
{
temp = arr.iter().rev().skip(1).next().unwrap() % arr.iter().last().unwrap();
*arr.iter_mut().rev().skip(1).next().unwrap() = *arr.iter().last().unwrap();
*arr.iter_mut().last().unwrap() = temp;
if *arr.iter().last().unwrap() == 0
{
arr.pop();
}
}
return arr.pop();
}
//Наименьшее общее кратное
fn nok(arr: &[i64]) -> std::option::Option<i64>
{
match arr.len()
{
0 | 1 => None,
_ => {
let mut arr = arr.to_vec();
let mut acc = 1;
for index in 0..arr.len()-1
{
for index1 in 1..arr.len()
{
if index == index1
{
continue;
}
acc *= euclidean_algorithm(&[arr[index], arr[index1]]).unwrap();
}
}
Some(arr.iter().product::<i64>().abs() / acc)
}
}
}
fn main() {
let arr = vec![10, 45, 95];
println!("{} {}", euclidean_algorithm(&arr).unwrap(), nok(&arr).unwrap());
}