1、给定两个字符串,请编写程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。这里规定【大小写为不同字符】,且考虑字符串重点空格。给定一个string s1和一个string s2,请返回一个bool,代表两串是否重新排列后可相同。 保证两串的长度都小于等于5000。
Go
package main
import (
"fmt"
"strings"
)
func isSomeStr(str1 string, str2 string) bool {
if len(str1) > 5000 || len(str2) > 5000 || len(str1) != len(str2) {
return false
}
for _, s := range str1 {
if strings.Count(str1, string(s)) != strings.Count(str2, string(s)) {
return false
}
}
/*自己的思路
charmap := make(map[rune]int)
for _, s := range str1 {
charmap[s]++
}
for _, s := range str2 {
charmap[s]--
}
for _, v := range charmap {
if v != 0 {
return false
}
}*/
return true
}
func main() {
fmt.Printf("is some :%v", isSomeStr("qsqq", "qqqs"))
}
2、请实现一个算法,在不使用【额外数据结构和储存空间】的情况下,翻转一个给定的字符串(可以使用单个过程变量)。给定一个string,请返回一个string,为翻转后的字符串。保证字符串的长度小于等于5000。
Go
package main
import (
"fmt"
)
func reverseString(strtmp []rune) (string, error) {
sl := len(strtmp)
if sl > 5000 {
return "", fmt.Errorf("invaild input string")
}
for i := 0; i < sl/2; i++ {
strtmp[i], strtmp[sl-i-1] = strtmp[sl-i-1], strtmp[i]
}
return string(strtmp), nil
}
func main() {
str0 := "世界你好"
str1, _ := reverseString([]rune(str0))
fmt.Printf("str0:%s, str1:%s", str0, str1)
}
3、使用两个 goroutine 交替打印序列,一个 goroutine 打印数字, 另外一个 goroutine 打印字母, 最终效果如下:
12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728
Go
/*
使用两个 goroutine 交替打印序列,一个 goroutine 打印数字, 另外一个 goroutine 打印字母, 最终效果如下:
12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ
*/
package main
import (
"fmt"
"sync"
)
const (
PRINT_COUNT = 2
)
func main() {
letterCh, numCh := make(chan struct{}, 1), make(chan struct{}, 1) // 使用缓冲通道避免死锁
var wg sync.WaitGroup
wg.Add(2)
go func() {
defer wg.Done()
i := 1
for i <= 26 {
<-numCh
for j := 0; j < PRINT_COUNT && i <= 26; j++ {
fmt.Printf("%d", i)
i++
}
letterCh <- struct{}{}
}
}()
go func() {
defer wg.Done()
i := 'A'
for i <= 'Z' {
<-letterCh
for j := 0; j < PRINT_COUNT && i <= 'Z'; j++ {
fmt.Printf("%c", i)
i++
}
// 如果数字还没打印完,继续发送信号给数字goroutine
if i <= 'Z' {
numCh <- struct{}{}
}
}
}()
numCh <- struct{}{} // 启动信号
wg.Wait()
}
5、假设有一个超长的切片,切片的元素类型为int,切片中的元素为乱序排序。限时5秒,使用多个goroutine查找切片中是否存在给定的值,在查找到目标值或者超时后立刻结束所有goroutine的执行。
比如,切片 [23,32,78,43,76,65,345,762,......915,86],查找目标值为 345 ,如果切片中存在,则目标值输出"Found it!"并立即取消仍在执行查询任务的goroutine。
如果在超时时间未查到目标值程序,则输出"Timeout!Not Found",同时立即取消仍在执行的查找任务的goroutine。
Go
package main
import (
"context"
"fmt"
"sync"
"time"
)
const (
ROUTINE_NUM_MAX = 10
SLICE_SIZE_MAX = 5000
)
func searchNum(ctx context.Context, subs []int, tgt int, wg *sync.WaitGroup, resultCh chan bool) {
defer wg.Done()
for _, v := range subs {
select {
case <-ctx.Done():
return
default:
if tgt == v {
resultCh <- true
}
}
}
}
func searchNumWithTimeout(s []int, tgt int, timeout time.Duration) bool {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
var wg sync.WaitGroup
resultCh := make(chan bool, 1)
segSize := len(s) / ROUTINE_NUM_MAX
for i := 0; i < ROUTINE_NUM_MAX; i++ {
start := i * segSize
end := start + segSize
if i == ROUTINE_NUM_MAX-1 {
end = len(s)
}
subs := s[start:end]
wg.Add(1)
go searchNum(ctx, subs, tgt, &wg, resultCh)
}
go func() {
wg.Wait()
close(resultCh)
}()
select {
case <-ctx.Done():
fmt.Printf("Timeout!Not Found222\n")
return false
case res := <-resultCh:
if res {
return true
}
return false
}
}
func simSlice(size int) []int {
s := make([]int, size)
for i := 0; i < size; i++ {
s[i] = i
}
return s
}
func main() {
s := simSlice(SLICE_SIZE_MAX)
target := 11111
timeout := 5 * time.Second
res := searchNumWithTimeout(s, target, timeout)
if res == true {
fmt.Printf("Found it!\n")
} else {
fmt.Printf("Timeout!Not Found333")
}
}