Skip to content

Instantly share code, notes, and snippets.

Created December 15, 2016 03:40
Show Gist options
  • Save anonymous/64479f669c7aa52ff55f3a1ad364f763 to your computer and use it in GitHub Desktop.
Save anonymous/64479f669c7aa52ff55f3a1ad364f763 to your computer and use it in GitHub Desktop.
Shared via Rust Playground
// [Rust で 言語処理100本ノック 第1章 前半 - 僕とコードとブルーハワイ](http://equal-001.hatenablog.com/entry/2016/12/14/232933)
// にコメントフォームがなかったのでコードぶん投げます
//# 00. 文字列の逆順
//文字列"stressed"の文字を逆に(末尾から先頭に向かって)並べた文字列を得よ.
fn no_00() -> String {
let s = "stressed";
s.chars()
.rev()
// 型を入れないとエラーになるのはcollectがジェネリックなため、推論出来ないから。
// このケースでは返り値で宣言していて推論出来るので宣言不要
.collect()
}
// # 01. 「パタトクカシーー」
// 「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ.
fn no_01() -> String {
let s = "パタトクカシーー";
// chars().enumerate()がくっついたやつ
s.char_indices()
// collectでStringが作れるので要素で条件分岐したいだけならfilterが便利
// クロージャの引数である程度パターンマッチ出来る
.filter(|&(i, _)| i % 2 == 0)
.map(|(_, c)| c)
.collect()
}
// # 02. 「パトカー」+「タクシー」=「パタトクカシーー」
// 「パトカー」+「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ.
fn no_02() -> String {
let s1 = "パトカー";
let s2 = "タクシー";
s1.chars()
// 多少技巧的だけど2つのイテレータを1つにくっつけることも可能。flat_mapで「イテレータのイテレータ」からただのイテレータに潰せる
.zip(s2.chars())
// こちらもパターンマッチでタプルをバラせる
.flat_map(|(c1, c2)| vec![c1, c2])
.collect()
}
// # 03. 円周率
// "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics."という文を単語に分解し,各単語の(アルファベットの)文字数を先頭から出現順に並べたリストを作成せよ.
fn no_03() -> Vec<usize> {
let s = "Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.";
s.split(&[' ', ',', '.'] as &[char])
.filter(|s| s.len() != 0)
.map(|s| s.len())
.collect()
}
// # 04. 元素記号
// "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can."という文を単語に分解し,1, 5, 6, 7, 8, 9, 15, 16, 19番目の単語は先頭の1文字,それ以外の単語は先頭に2文字を取り出し,取り出した文字列から単語の位置(先頭から何番目の単語か)への連想配列(辞書型もしくはマップ型)を作成せよ.
use std::collections::HashMap;
fn no_04() -> HashMap<String, usize> {
let s = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.";
s.split(&[' ', ',', '.'] as &[char])
.filter(|s| s.len() != 0)
.enumerate()
// enumerateのoriginが0なので1 originに修正
.map(|(i, w)| (i+1, w))
.map(|(i, word)|
// insertしないのでmatchで処理出来る
match i {
1 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 19 => {
(word[0..1].to_string(), i)
},
_ => {
(word[0..2].to_string(), i)
}
}
)
// ハッシュマップもcollect出来る
.collect()
}
fn main() {
println!("No1: {}", no_00());
println!("No2: {}", no_01());
println!("No3: {}", no_02());
// リストやハッシュマップは {:?} フォーマッタでデバッグ出力出来る
println!("No4: {:?}", no_03());
println!("No5: {:?}", no_04());
// # その他
{
// 任意の(Displayを実装した)型 -> Stringは format!が使えます
let ui: usize = 3;
let usize_str: String = format!("{}", ui);
println!("{}", usize_str);
// あるいは大抵の型にto_stringが実装されています。
let ui: usize = 3;
let usize_str: String = ui.to_string();
println!("{}", usize_str);
}
{
// &strのto_stringとto_ownedは今では全く同じです。
// 昔はto_stringは色々な型に使える代わりに遅かったのですが今は最適化でto_ownedと同じ速度になりました。
// なのでto_ownedはやめてto_stringを使いましょう。
}
{
// 文字列の結合にもformat!が使えます
let str1 = "foo";
let str2 = "bar";
let str1str2 = format!("{}{}", str1, str2);
println!("{}", str1str2);
// あるいは足されるstrがString、足すstrが&strなら+も使えます
// +は足されるstrを書き換えるイメージで、足されるstrは使えなくなります。
let str1 = "foo".to_string();
let str2 = "bar";
let str1str2 = str1 + str2;
println!("{}", str1str2);
// error
// println!("{}", str1);
// こっちはOK
println!("{}", str2);
// 因みに両方Stringでも足す方を&すれば+は使えます
let str1 = "foo".to_string();
let str2 = "bar".to_string();
let str1str2 = str1 + &str2;
println!("{}", str1str2);
}
{
// Rustにin演算子はないので&[T]のcontainsを使いましょう。
for i in 0..20 {
println!("{}: {}", i, [1, 5, 6, 7, 8, 9, 15, 16, 19].contains(&i))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment