151. Remove string trailing path separator
Remove last character from string p, if this character is the file path separator of current platform.
Note that this also transforms unix root path "/" into the empty string!
删除字符串尾部路径分隔符
package main import ( "fmt" "io/ioutil" "os" "strings" ) func main() { p := somePath() fmt.Println(p) sep := fmt.Sprintf("%c", os.PathSeparator) p = strings.TrimSuffix(p, sep) fmt.Println(p) } func somePath() string { dir, err := ioutil.TempDir("", "") if err != nil { panic(err) } p := fmt.Sprintf("%s%c%s%c", dir, os.PathSeparator, "foobar", os.PathSeparator) return p }
/tmp/067319278/foobar/ /tmp/067319278/foobar
or
package main import ( "fmt" "io/ioutil" "os" "path/filepath" "strings" ) func main() { p := somePath() fmt.Println(p) sep := fmt.Sprintf("%c", filepath.Separator) p = strings.TrimSuffix(p, sep) fmt.Println(p) } func somePath() string { dir, err := ioutil.TempDir("", "") if err != nil { panic(err) } p := fmt.Sprintf("%s%c%s%c", dir, os.PathSeparator, "foobar", os.PathSeparator) return p }
/tmp/065654753/foobar/ /tmp/065654753/foobar
fn main() { { let p = "/tmp/"; let p = if ::std::path::is_separator(p.chars().last().unwrap()) { &p[0..p.len() - 1] } else { p }; println!("{}", p); } { let p = "/tmp"; let p = if ::std::path::is_separator(p.chars().last().unwrap()) { &p[0..p.len() - 1] } else { p }; println!("{}", p); } }
/tmp /tmp
or
fn main() { { let mut p = "/tmp/"; p = p.strip_suffix(std::path::is_separator).unwrap_or(p); println!("{}", p); } { let mut p = "/tmp"; p = p.strip_suffix(std::path::is_separator).unwrap_or(p); println!("{}", p); } }
/tmp /tmp
152. Turn a character into a string
Create string s containing only the character c.
将字符转换成字符串
package main import ( "fmt" "os" ) func main() { var c rune = os.PathSeparator fmt.Printf("%c \n", c) s := fmt.Sprintf("%c", c) fmt.Printf("%#v \n", s) }
/ "/"
fn main() { let c = 'a'; let s = c.to_string(); println!("{}", s); }
153. Concatenate string with integer
Create string t as the concatenation of string s and integer i.
连接字符串和整数
package main import ( "fmt" ) func main() { s := "Hello" i := 123 t := fmt.Sprintf("%s%d", s, i) fmt.Println(t) }
fn main() { let s = "Foo"; let i = 1; let t = format!("{}{}", s, i); println!("{}" , t); }
154. Halfway between two hex color codes
Find color c, the average between colors c1, c2.
c, c1, c2 are strings of hex color codes: 7 chars, beginning with a number sign # . Assume linear computations, ignore gamma corrections.
求两个十六进制颜色代码的中间值
package main import ( "fmt" "strconv" "strings" ) // For concision, halfway assume valid inputs. // Caller must have explicitly checked that c1, c2 are well-formed color codes. func halfway(c1, c2 string) string { r1, _ := strconv.ParseInt(c1[1:3], 16, 0) r2, _ := strconv.ParseInt(c2[1:3], 16, 0) r := (r1 + r2) / 2 g1, _ := strconv.ParseInt(c1[3:5], 16, 0) g2, _ := strconv.ParseInt(c2[3:5], 16, 0) g := (g1 + g2) / 2 b1, _ := strconv.ParseInt(c1[5:7], 16, 0) b2, _ := strconv.ParseInt(c2[5:7], 16, 0) b := (b1 + b2) / 2 c := fmt.Sprintf("#%02X%02X%02X", r, g, b) return c } func main() { c1 := "#15293E" c2 := "#012549" if err := checkFormat(c1); err != nil { panic(fmt.Errorf("Wrong input %q: %v", c1, err)) } if err := checkFormat(c2); err != nil { panic(fmt.Errorf("Wrong input %q: %v", c2, err)) } c := halfway(c1, c2) fmt.Println("The average of", c1, "and", c2, "is", c) } func checkFormat(color string) error { if len(color) != 7 { return fmt.Errorf("Hex colors have exactly 7 chars") } if color[0] != '#' { return fmt.Errorf("Hex colors start with #") } isNotDigit := func(c rune) bool { return (c < '0' || c > '9') && (c < 'a' || c > 'f') } if strings.IndexFunc(strings.ToLower(color[1:]), isNotDigit) != -1 { return fmt.Errorf("Forbidden char") } return nil }
package main import ( "fmt" "strconv" "strings" ) // For concision, halfway assume valid inputs. // Caller must have explicitly checked that c1, c2 are well-formed color codes. func halfway(c1, c2 string) string { var buf [7]byte buf[0] = '#' for i := 0; i < 3; i++ { sub1 := c1[1+2*i : 3+2*i] sub2 := c2[1+2*i : 3+2*i] v1, _ := strconv.ParseInt(sub1, 16, 0) v2, _ := strconv.ParseInt(sub2, 16, 0) v := (v1 + v2) / 2 sub := fmt.Sprintf("%02X", v) copy(buf[1+2*i:3+2*i], sub) } c := string(buf[:]) return c } func main() { c1 := "#15293E" c2 := "#012549" if err := checkFormat(c1); err != nil { panic(fmt.Errorf("Wrong input %q: %v", c1, err)) } if err := checkFormat(c2); err != nil { panic(fmt.Errorf("Wrong input %q: %v", c2, err)) } c := halfway(c1, c2) fmt.Println("The average of", c1, "and", c2, "is", c) } func checkFormat(color string) error { if len(color) != 7 { return fmt.Errorf("Hex colors have exactly 7 chars") } if color[0] != '#' { return fmt.Errorf("Hex colors start with #") } isNotDigit := func(c rune) bool { return (c < '0' || c > '9') && (c < 'a' || c > 'f') } if strings.IndexFunc(strings.ToLower(color[1:]), isNotDigit) != -1 { return fmt.Errorf("Forbidden char") } return nil }
use std::str::FromStr; use std::fmt; #[derive(Debug)] struct Colour { r: u8, g: u8, b: u8 } #[derive(Debug)] enum ColourError { MissingHash, InvalidRed, InvalidGreen, InvalidBlue } impl fmt::Display for Colour { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "#{:02x}{:02x}{:02x}", self.r, self.g, self.b) } } impl FromStr for Colour { type Err = ColourError; fn from_str(s: &str) -> Result<Self, Self::Err> { if !s.starts_with('#') { Err(ColourError::MissingHash) } else { Ok(Colour { r: u8::from_str_radix(&s[1..3], 16).map_err(|_| ColourError::InvalidRed)?, g: u8::from_str_radix(&s[3..5], 16).map_err(|_| ColourError::InvalidGreen)?, b: u8::from_str_radix(&s[5..7], 16).map_err(|_| ColourError::InvalidBlue)? }) } } } fn mid_colour(c1: &str, c2: &str) -> Result<String, ColourError> { let c1 = c1.parse::<Colour>()?; let c2 = c2.parse::<Colour>()?; let c = Colour { r: (((c1.r as u16) + (c2.r as u16))/2) as u8, g: (((c1.g as u16) + (c2.g as u16))/2) as u8, b: (((c1.b as u16) + (c2.b as u16))/2) as u8 }; Ok(format!("{}", c)) } fn main() { println!("{}", mid_colour("#15293E", "#012549").unwrap()) }
155. Delete file
Delete from filesystem the file having path filepath.
删除文件
package main import ( "fmt" "io/ioutil" "os" ) func main() { for _, filepath := range []string{ "/tmp/foo.txt", "/tmp/bar.txt", "/tmp/foo.txt", } { err := os.Remove(filepath) if err == nil { fmt.Println("Removed", filepath) } else { fmt.Fprintln(os.Stderr, err) } } } func init() { err := ioutil.WriteFile("/tmp/foo.txt", []byte(`abc`), 0644) if err != nil { panic(err) } }
Removed /tmp/foo.txt remove /tmp/bar.txt: no such file or directory remove /tmp/foo.txt: no such file or directory
use std::fs; fn main() { let filepath = "/tmp/abc"; println!("Creating {}", filepath); let _file = fs::File::create(filepath); let b = std::path::Path::new(filepath).exists(); println!("{} exists: {}", filepath, b); println!("Deleting {}", filepath); let r = fs::remove_file(filepath); println!("{:?}", r); let b = std::path::Path::new(filepath).exists(); println!("{} exists: {}", filepath, b); }
Creating /tmp/abc /tmp/abc exists: true Deleting /tmp/abc Ok(()) /tmp/abc exists: false
156. Format integer with zero-padding
Assign to string s the value of integer i in 3 decimal digits. Pad with zeros if i < 100. Keep all digits if i ≥ 1000.
用零填充格式化整数
package main import ( "fmt" ) func main() { for _, i := range []int{ 0, 8, 64, 256, 2048, } { s := fmt.Sprintf("%03d", i) fmt.Println(s) } }
000 008 064 256 2048
fn main() { let i = 1; let s = format!("{:03}", i); println!("{}", s); let i = 1000; let s = format!("{:03}", i); println!("{}", s); }
001 1000
157. Declare constant string
Initialize a constant planet with string value "Earth".
声明常量字符串
package main import ( "fmt" ) const planet = "Earth" func main() { fmt.Println("We live on planet", planet) }
fn main() { const PLANET: &str = "Earth"; println!("{}", PLANET); }
158. Random sublist
Create a new list y from randomly picking exactly k elements from list x.
It is assumed that x has at least k elements. Each element must have same probability to be picked. Each element from x must be picked at most once. Explain if the original ordering is preserved or not.
随机子列表
package main import ( "fmt" "math/rand" ) func main() { type T string x := []T{"Alice", "Bob", "Carol", "Dan", "Eve", "Frank", "Grace", "Heidi"} k := 4 y := make([]T, k) perm := rand.Perm(len(x)) for i, v := range perm[:k] { y[i] = x[v] } fmt.Printf("%q", y) }
use rand::prelude::*; let mut rng = &mut rand::thread_rng(); let y = x.choose_multiple(&mut rng, k).cloned().collect::<Vec<_>>();
159. Trie
Define a Trie data structure, where entries have an associated value. (Not all nodes are entries)
前缀树/字典树
package main import ( "fmt" "unicode/utf8" ) type Trie struct { c rune children map[rune]*Trie isLeaf bool value V } type V int func main() { t := NewTrie(0) for s, v := range map[string]V{ "to": 7, "tea": 3, "ted": 4, "ten": 12, "A": 15, "i": 11, "in": 5, "inn": 9, } { t.insert(s, v) } fmt.Println(t.startsWith("te", "")) } func NewTrie(c rune) *Trie { t := new(Trie) t.c = c t.children = map[rune]*Trie{} return t } func (t *Trie) insert(s string, value V) { if s == "" { t.isLeaf = true t.value = value return } c, tail := cut(s) child, exists := t.children[c] if !exists { child = NewTrie(c) t.children[c] = child } child.insert(tail, value) } func (t *Trie) startsWith(p string, accu string) []string { if t == nil { return nil } if p == "" { var result []string if t.isLeaf { result = append(result, accu) } for c, child := range t.children { rec := child.startsWith("", accu+string(c)) result = append(result, rec...) } return result } c, tail := cut(p) return t.children[c].startsWith(tail, accu+string(c)) } func cut(s string) (head rune, tail string) { r, size := utf8.DecodeRuneInString(s) return r, s[size:] }
struct Trie { val: String, nodes: Vec<Trie> }
160. Detect if 32-bit or 64-bit architecture
Execute f32() if platform is 32-bit, or f64() if platform is 64-bit.
This can be either a compile-time condition (depending on target) or a runtime detection.
检测是32位还是64位架构
package main import ( "fmt" "strconv" ) func main() { if strconv.IntSize == 32 { f32() } if strconv.IntSize == 64 { f64() } } func f32() { fmt.Println("I am 32-bit") } func f64() { fmt.Println("I am 64-bit") }
fn main() { match std::mem::size_of::<&char>() { 4 => f32(), 8 => f64(), _ => {} } } fn f32() { println!("I am 32-bit"); } fn f64() { println!("I am 64-bit"); }