1.上周作业
上周有三个练习,写的比较局限,更新了写法
练习1:输出100-200之间的素数及其个数
package main
import (
"fmt"
)
func IsPrime(a int) bool {
for i := 2;i < a;i++ {
if a%i == 0 {
return false
}
}
return true
}
func main() {
var n int
var m int
var k int
fmt.Scanf("%d %d",&n,&m)
for j := n;i < m + 1;j++ {
if IsPrime(j) == true {
fmt.Printf("%d",j)
k = k +1
}
}
fmt.Printf("There are %d 素数",k)
}
}
重点说一下这里为什么在Scanf函数中传递变量地址?
从上面的代码中声明了变量n,m,两者默认值为0,fmt包调用Scanf函数请求在终端输入两个数,这里传入了两个变量n与m,注意这里的n与m是前面全局变量n与m的副本,为了区分,我们将其用n1 m1,这个时候如果终端输入数值,假如是100,那么n1就等于100,但是n不等于100,仍然等于0,这就会导致后面是用变量n报错,所以需要传入一个地址&n,分配的内存地址与n一样,输入100时,n的值会变成100
该代码比练习1-输出素数更灵活,可以自由控制范围,但是缺点就是需要手动输入范围数值
练习2:输出100-1000之间的水仙花数,水仙花数是指该数的各个位的立方和等于该数
package main
import (
"fmt"
"strconv"
)
func IsShui(a int) bool {
var str string
str = strconv.Itoa(a)
substr1 := str[0:1]
substr2 := str[1:2]
substr3 := str[2:]
num1,_ := strconv.Atoi(substr1)
num2,_ := strconv.Atoi(substr2)
num3,_ := strconv.Atoi(substr3)
if num1 * num1 * num1 + num2 * num2 * num2 + num3 * num3 * num3 == a {
return true
}
return false
}
func main() {
var n int
var m int
fmt.Scanf("%d %d",&n,&m)
for i := n;i < m + 1;i++ {
fmt.Printf("%d\n",i)
}
}
上面在进行计算进行了字符串与整型的类型转换,其实不必这样,获取一个数字的个、十、百位有更简单的方法
package main
import (
"fmt"
)
func IsShui(a int) bool {
var i int
var j int
var k int
i = a % 10
j = (a / 10) % 10
k = (a / 100) % 10
num := i * i * i + j * j * j + k * k * k
if num == a {
return true
}
return false
}
func main() {
var n int
var m int
fmt.Scanf("%d%d",&n,&m)
for p := n;p < m;p++ {
if IsShui(p) == true {
fmt.Printf("%d\n",p)
}
}
}
其实还可以利用go里面所有的字符和整数都是通过ascii码来存储的,如果用每一个数字对应的ascii码减去字符'0'就可以获得该数字的对应值,但是该值默认是byte型,需要int类型转换
package main
import (
"fmt"
"strconv"
)
func IsShui(j int) bool {
var result int = 0
str := strconv.Itoa(j)
for i := 0;i < len(str);i++ {
num := int(str[i] - '0') // ascii码值相减获取该数值
result = result + num*num*num
}
result1,_ :== strconv.Atoi(str)
if result == result1 {
return true
}
return false
}
func main() {
var n string
var m string
fmt.Scanf("%s%s",&n,&m)
num1,_ := strconv.Atoi(n)
num2,_ := strconv.Atoi(m)
for j := num1;j < num2;j++ {
if IsShui(j) == true {
fmt.Printf("%d\n",j)
}
}
}
写了一大堆其实还没有前面两种方式简单,之所以这样写主要是想测试一下通过ascii码来获取对应的数值
练习3:取一个数n,计算1!+ 2! + 3! + ... + n!
package main
import (
"fmt"
)
func JieChen(a int) int {
var sum int
var s int = 1
for i := 1;i <= a;i++{
s = s * i
sum += s
}
return sum
}
func main() {
var n int
fmt.Scanf("%d",&n)
s1 := Jiechen(n)
fmt.Println(s1)
}
上面的代码只用了一个for循环
经过一段时间学习,自己也有了一点go代码的小心得,下面是我自己重新写的一个例子,原则上是入口函数里只进行输入输出,功能部分均自定义函数实现,尽量让程序更加具有可读性
package main
import (
"fmt"
)
func Sum(n int) (sum int) {
for i := 1;i <= n;i++ {
result := Add(i)
sum += result
}
return
}
func Add(i int) (result int) {
for a := 1;a <= i;a++ {
result *= a
}
return
}
func main() {
var n int
fmt.Scanf("%d",&n)
result := Sum(n)
fmt.Printf("result=%d\n",result)
}
这样的写法比老师写的复杂,多用了一个循环,但理解起来更清晰
2.strings与strconv
利用函数strings.HasPrefix、strings.HasSuffix、strings.Index、strings.LastIndex来判断字符串
1:使用函数strings.HasPrefix(s string prefix string) bool判断字符串s是否以prefix开头
2:使用函数strings.HasSuffix(s string prefix string) bool判断字符串s是否以prefix结尾
3: 使用函数strings.Index(s string str string) int判断str首次在s出现的位置,如果没有出现则返回-1
str
4: 使用函数strings.LastIndex(s string str string) int判断str在s中最后出现的位置,如果没有则返回-1
先附上我自己写的代码
package main
import (
"fmt"
"strings"
)
func IsHTTPHead(str1 string) {
a := strings.HasPrefix(str "http://")
if a == true {
fmt.Println(str1)
} else {
str1 = "http://" + str1
fmt.Println(str1)
}
}
func IsHTTPTail(str1 string) {
a := strings.HasSuffix(str1,"/")
if a == true {
fmt.Printfln(str1)
} else {
str1 = str1 + "/"
fmt.Println(str1)
}
}
func IsIndex(str1 string) {
a := strings.Index(str1,"linuxwt")
if a == -1 {
fmt.Println("不存在")
} else if a == 4 {
fmt.Println("位置正确")
} else {
fmt.Println("位置不正确")
}
}
func IsLastIndex(str1 string) {
a := strings.LastIndex(str1,"/")
if a == -1 {
fmt.Println("不存在")
} else if a == 10 {
fmt.Println("位置正确")
} else {
fmt.Println("位置不正确")
}
}
func main() {
var (
str1 string
str2 string
str3 string
str4 string
)
fmt.Scanf("%s%s%s%s",&str1,&str2,&str3,&str4)
IsHTTPHead(str1)
IsHTTPTail(str2)
IsIndex(str3)
IsLASTIndex(str4)
}
编译执行
下面是老师写的
package main
import (
"fmt"
"strings"
)
// URLProcess is a function for 判断字符串是否以某个字符(http://)串开头
func URLProcess(url string) string {
result := strings.HasPrefix(url,"http://")
if !result {
url = fmt.Sprintf("http://%s",url)
}
return url
}
// PathProcess is a function for 判断字符串是否以某个字符串(/)结尾
func PathProcess(path string) string {
result := strings.HasSuffix(path,"/")
if !result {
path = fmt.Sprintf("%s/",path)
}
return path
}
// FirstIndex is a function for 判断子字符串(baidu)在字符串中首次出现的位置
func FirstIndex(first string) string {
result := strings.Index(first,"baidu")
if result == 4 {
first = fmt.Sprintf("判断正确")
} else if result == -1 {
first = fmt.Sprintf("不存在")
} else {
first = fmt.Sprintf("判断错误")
}
return first
}
// EndIndex is a function for 判断子字符串(com)在字符串中最后出现的位置
func EndIndex(end string) string {
result := strings.LastIndex(end,"com")
if result == 10 {
end = fmt.Sprintf("判断正确")
} else if result == -1 {
end = fmt.Sprintf("不存在")
} else {
end = fmt.Sprintf("判断错误")
}
return end
}
func main() {
var (
url string
path string
first string
end string
)
fmt.Scanf("%s%s%s%s",&url,&path,&first,&end)
url = URLProcess(url)
path = PathProcess(path)
first = FirstIndex(first)
end = EndIndex(end)
fmt.Println(url)
fmt.Println(path)
fmt.Println(first)
fmt.Println(end)
}
编译执行输出
5、字符串替换函数strings.Replace(str string,old string,new string,n int)n为替换的次数
6、字符串计数函数strings.Count(str string,substr string)
7、重复k次str函数strings.Repeat(str string,k int)
8、字符串转换为小写函数strings.ToLower(str string)
9、字符串转换为大写函数strings.ToUpper(str string)
下面附上代码例子
package main
import (
"strings"
"fmt"
)
// Replace is a function for 字符串替换输出
func Repalce(replstr string) string {
result := strings.Replace(replstr,"wa",3)
return result
}
// Count is a function for 字符串计数输出
func Count(counstr string) int {
result := strings.Count(counstr,"wa")
return result
}
// Repeat is a function for 字符串重复输出
func Repeat(repestr string) string {
result := strings.Repeat(repestr,2)
return result
}
// Lower is a function for 字符串转换为小写
func Lower(lowestr string) string {
result := strings.ToLower(lowestr)
return result
}
// Upper is a function for 字符串转换为大写
func Upper(uppestr string) string {
result := strings.ToUpper(uppestr)
return result
}
func main() {
var (
replstr string = "wawawawt"
counstr string = "wawawawt"
repestr string = "wawawawt"
lowestr string = "WAWAWAWT"
uppestr string = "wawawawt"
k int
)
replstr = Replace(replstr)
k = Count(counstr)
repestr = Repeat(repestr)
lowestr = Lower(lowestr)
uppestr = Upper(uppestr)
fmt.Printf("%s\n",replstr)
fmt.Printf("%d\n",k)
fmt.Printf("%s\n",repestr)
fmt.Printf("%s\n",lowestr)
fmt.Printf("%s\n",uppestr)
}
编译执行输出
10、strings.TrimSpace(str string)去掉字符串首尾空白
11、strings.Trim(str string,cut string)去掉字符串首尾指定的子串
12、strings.TrimLeft(str string,cut string)去掉字符串首指定的子串
14、strings.TrimRight(str string,cut string)去掉字符串尾指定的子串
代码:
package main
import (
"fmt"
"strings"
)
// TrimSp is afunction for 去掉字符串首尾空白
func TrimSp(spacstr string) string {
result := strings.TrimSpace(spacstr)
return result
}
// Trim is a function for 去掉字符串首尾指定的字符串
func Trim(htstr string) string {
result := strings.Trim(htstr,"ab")
return result
}
// Ltrim is a function for 去掉字符串首指定的字符串
func Ltrim(lstr string) string {
result := strings.TrimLeft(lstr,"ab")
return result
}
// Rtrim is a function for 去掉字符串尾指定的字符串
func Rtrim(rstr string) string {
result := strings.TrimRight(rstr,"ab")
return result
}
func main() {
var (
spacstr string = " abc "
htstr string = "abbadabcabba"
lstr string = "abbacdab"
rstr string = "abcdabba"
)
spacstr = TrimSp(spacstr)
htstr = Trim(htstr)
lstr = Ltrim(lstr)
rstr = Rtrim(rstr)
fmt.Printf("%s\n",spacstr)
fmt.Printf("%s\n",htstr)
fmt.Printf("%s\n",lstr)
fmt.Printf("%s\n",rstr)
}
编译执行
15、strings.Fields返回字符串空格分隔的子串slice
16、strings.Split返回字符串非空格分隔的子串slice
代码
package main
import (
"fmt"
"strings"
)
// Field is a function for 返回字符串空格分隔的子串slice,只能针对以空格分隔子串的字符串
func Field(field string) []string {
result := strings.Fields(field)
return result
}
// Split is a function for 返回字符串非空格(这里是逗号)分隔的子串slice,但slice仍然是以空格分隔
func Split(split string) []string {
result := strings.Split(split,",")
return result
}
func main() {
var (
field string = "abc def ghi"
split string = "abc,def,ghi"
field1 []string
split1 []string
)
field1 = Field(field)
split1 = Split(split)
fmt.Printf("%s\n",field1)
fmt.Printf("%s\n",split1)
}
编译执行
17、strings.Join(s []string,sep string)用sep把s中的元素连接起来
package main
import (
"fmt"
"strings"
)
// Slice1 is a function for 使用空格将[]string中的元素连接起来
func Slice1(slice []string) string {
result ;= strings.Join(slice," ")
return result
}
// Slice2 is a function for 使用逗号将[]string中的元素连接起来
func Slice2(slice []string) string {
result := strings.Join(slice,",")
return result
}
func main() {
var (
slice []string = []string{"abc","def","ghi"}
str1 string
str2 string
)
str1 = Slice1(slice)
str2 = Slice2(slice)
fmt.Printf("%s\n",str1)
fmt.Printf("%s\n",str2)
fmt.Printf("%q\n",str1)
fmt.Printf("%q\n",str2)
}
编译执行
18、strconv.Itoa(n int)整数转换成字符串
19、strconv.Atoi(str string) (int,error)字符串转换成整数
代码
package main
import (
"fmt"
"strconv"
)
// Exchange1 is a function for 整数转换成字符串
func Exchange1(n int) string {
result := strconv.Itoa(n)
return result
}
// Exchange2 is a function for 字符串转换成整数
func Exchange2(str string) int {
result,err := strconv.Atoa(str)
if err != nil {
fmt.Printf("can not convert %s to int.",str)
}
return result
}
func main() {
var (
n int
str string
n1 string
str1 int
)
fmt.Scanf("%d%s",&n,&str)
n1 = Exchange1(n)
str1 = Exchange2(str)
fmt.Printf("%T %d\n",n,n)
fmt.Printf("%T %s\n",str,str)
fmt.Printf("%T %d\n",n1,n1)
fmt.Printf("%T %s\n",str1,str1)
}
编译执行
前面学习了strings、strconv包的常规使用,例子都是我自己写的,都采用自定义调用函数的写法作了基本的学习,下面是老师给的例子,主要是方便学习相关知识,抄录下来与自己写的作比较
package main
import (
"fmt"
"strings"
"strconv"
)
func main() {
str := " hello world abc \n\r" // \n为换行\r为回车
result := strings.Replace(str,"world","you",1)
fmt.Println("Replace:",result)
count = strings.Count(str,"l")
fmt.Println("Count:",count)
result = strings.Repeat(str,3)
fmt.Println("Repeat:",result)
result = strings.ToLower(str)
fmt.Println("ToLower:",result)
result = strings.ToUpper(str)
fmt.Println("ToUpper:",result)
result = strings.TrimSpace(str)
fmt.Println("TrimSpace:",result)
result = strings.Trim(str," \n\r")
fmt.Println("Trim:",result)
result = strings.TrimLeft(str," \n\r")
fmt.Println("TrimLeft:",result)
result = strings.TrimRight(str," \n\r")
fmt.Println("TrimRight:"," \n\r")
fieldresult := strings.Fields(str)
fmt.Println("Fields:",fieldresult)
for i := 0;i < len(fieldresult);i++ {
fmt.Println(fieldresult[i])
}
splitresult := strings.Split(str)
fmt.Println("Split:",splitresult)
for i := 0;i < len(splitresult);i++ {
fmt.Println(splitresult[i])
}
result = strings.Join(fieldresult," ")
fmt.Println("Join:",result)
result = strings.Join(splitresult,"l")
fmt.Println("Join:",result)
result = strconv.Itoa(1000)
fmt.Println("Itoa:",result)
number,err := strconv.Atoi(result)
if err != nil {
fmt.Printf("can not convert %s to int.",result)
return
}
fmt,Println("Atoi:",number)
}
代码中的str变量是一个值类型,不会因为后面的操作而改变它的值,result这个变量第一次使用是在实现strings.Repalce函数功能时候,该函数返回值为字符串,所以后面在实现strings.Count与strconv.Atoi函数功能的时候不能使用result,因为这两者返回值类型为整型
3.time
获取当前时间并格式化输出
package main
import (
"fmt"
"time"
)
func main() {
now := time.Now()
fmt.Println(now.Format("2006/01/02 15:04:05"))
fmt.Printf("%s\n",now.Format("2006/01/02 15:04:05"))
fmt.Printf("%02d/%02d/%02d %02d:%02d:%02d",now.Year(),now.Month(),now.Day(),now.Hour(),now.Minute(),now.Second())
}
编译执行
time包里面还有一些常规的写法来表示时间单位
- time.Duration 纳秒
- time.Microsecond 微秒
- time.Millisecond 毫秒
- time.Second 秒
- time.Minute 分
- time.Hour
下面是一个简单统计某个程序运行时耗的例子
package main
import (
"fmt"
"time"
)
func Test() {
time.Sleep(time.Millisecond * 100)
}
func main() {
now := time.Now()
start := now.UnixNano()
Test()
end := now.UnixNano()
fmt.Printf("cost: %d us",(end - start)/1000)
}