牛客华为题库刷题记录

HJ1 字符串最后一个单词的长度

处理字符串输入使用了 bufio.NewScanner(os.Stdin) ,然后再循环 .Scan() 方法读取

思路:读入字符串,使用 strings.Split(字符串,分隔符)进行拆分为数组,然后读取最后一个数组的长度

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
    input := bufio.NewScanner(os.Stdin)
    for input.Scan(){
        arr:=strings.Split(input.Text(), " ")
        fmt.Println(len(arr[len(arr)-1]))
    }
}

HJ2 计算某字符出现次数

这里涉及到了两行的读取,使用 bufio.NewScanner(os.Stdin) 进行读取

bufio.NewScanner一行一行的读取fmt.Scan 是读取的时候遇到空格就停

计算某个字符出现的次数,使用strings.count(字符串, 要统计的字符)

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    a_string := scanner.Text()
    scanner.Scan()
    target := scanner.Text()
    a_string=strings.ToLower(a_string)
    target=strings.ToLower(target)
    count:=strings.Count(a_string, target)
    fmt.Println(count)
}

HJ3 明明的随机数

当标准输入的所有数据都被读取完毕时,scanner.Scan() 会返回 false,循环因此停止

注意, range 返回有两个数字,第一个是索引,第二个是值;不要写成了 for i := range keys ,i 是索引

字符串转换为数字 strcon.Atoi()

思路:把所有的随机数都读到map中相当于实现去重,然后再把map中的键读到切片中进行排序

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    hashmap := map[int]int{}
    scanner.Scan()
    _ =scanner.Text()
    for scanner.Scan(){
        num,_ := strconv.Atoi( scanner.Text())
        hashmap[num]++
    }
    keys := make([]int,0,len(hashmap))
    for key,_ := range hashmap{
        keys = append(keys, key)
    }
    sort.Ints(keys)
    for _,key:=range keys{
        fmt.Println(key)
    }
}

HJ4 按照长度分割字符串

题目要求不足8位的要添0占位,所以就先用求余运算得到需要添加0的个数先加上去。

添加0的方法:strings.Repeat("0",padding)

然后再分割,实际上就是通过向一个切片中,添加字符串切片实现

package main

import (
	"fmt"
	"strings"
)

func main() {
	var input string
	fmt.Scanf("%s",&input)
	remind := len(input) % 8
	if remind != 0 {
		padding := 8 - remind
		input = input + strings.Repeat("0", padding)
	}
    results := []string{}
    for i:=0;i<len(input);i=i+8{
        results=append(results, input[i:i+8])
    }
    for _,i:=range results{
        fmt.Println(i)
    }
}

HJ5 进制转换

用scanf输入按照16进制进去,然后就保存为int类型10进制了。

package main

import (
	"fmt"
)

func main() {
	var num int
	fmt.Scanf("0x%x", &num)
	fmt.Println(num)
}

HJ6 质数因子

一个数的最大质因数不会超过它的平方根;但是不排除它自身就是质数

思路:从2开始尝试能不能被整除,然后要求同一个数字不能再除之后除数才增加。就能实现被2 除完之后,4就没用了(因为他不是质数,也不会被打印出来)。最后再把 num 打印一下就好

package main

import (
	"fmt"
)

func main() {
	var num int
	fmt.Scanf("%d", &num)

	i := 2
	for i*i <= num {
		if num%i == 0 {
			num /= i
			fmt.Printf("%d ", i)
		} else {
			i++
		}
	}
    // 保证当num本来就是一个质数的时候,前面的流程处理完后,num还不为1
    if num > 2{
		fmt.Printf("%d ", num)
    }
}

HJ7 取近似值

取整函数:math.Ceil()向上取整;math.Floor()向下取整

package main

import (
	"fmt"
	"math"
)

func main() {
	var num float64
	fmt.Scan(&num)
	if num-math.Floor(num) >= 0.5 {
		fmt.Println(math.Ceil(num))
	} else {
		fmt.Println(math.Floor(num))
	}
}

HJ8 合并表记录

题目容易理解并简单,就是用map合并同项相加,最后再把map按照key排序输出。就是再string和int之间的转换多了一点

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
	"strings"
)

func main() {
	hashmap := map[string]int{}
	scanner := bufio.NewScanner(os.Stdin)
	keys := []int{}
	scanner.Scan()
	for scanner.Scan() {
		input := scanner.Text()
		inputs := strings.Split(input, " ")
		key := inputs[0]
		value, _ := strconv.Atoi(inputs[1])
		hashmap[key] = hashmap[key] + value
	}
	for key, _ := range hashmap {
		int_key, _ := strconv.Atoi(key)
		keys = append(keys, int_key)
	}
	sort.Ints(keys)
	for _, key := range keys {
		fmt.Printf("%s %d\n", strconv.Itoa(key), hashmap[strconv.Itoa(key)])
	}
}

HJ9 提取不重复的整数

思路:从右到左提取的话直接就是取余操作和除法操作

package main

import (
	"fmt"
)

func main() {
	var word int
	fmt.Scan(&word)
	var newnum int
	array := [10]int{}
	for word != 0 {
		lastnum := word % 10
		if array[lastnum] != 1 {
			array[lastnum] = 1
			newnum = newnum*10 + lastnum
		}
		word /= 10
	}
	fmt.Println(newnum)
}

HJ10 字符个数统计

有点太简单了,直接map,输出len(map)就秒了

package main

import (
    "fmt"
)

func main() {
   var str string
   fmt.Scan(&str)
   hashmap := map[byte]int{}
   for i,_:=range str{
    hashmap[str[i]]=i
   }
   fmt.Print(len(hashmap))
}

HJ11 数字颠倒

就是将数字从int读入,然后转为string;然后调用reverse

package main

import (
	"fmt"
	"strconv"
)

func main() {
	var num int
	fmt.Scan(&num)
	str := strconv.Itoa(num)
	str = reverse(str)
	fmt.Print(str)
}

func reverse(str string) string {
	// 将字符串转换为字符数组,以便可以修改其中的字符
	runes := []rune(str)
	for i, j := 0, len(runes)-1; i < len(runes)/2; i, j = i+1, j-1 {
		// 交换字符
		runes[i], runes[j] = runes[j], runes[i]
	}
	// 将字符数组转换回字符串并返回
	return string(runes)
}

HJ12 字符串反转

和上面一道题目一样的,处理字符串的反转。

在reverse函数内部,先把str string转换为rune,直接强制转换就好

然后再进行交换字符,最后返回的时候转换为string类型即可

func reverse (str string) string{
	runes := []rune(str)
	for i,j:=0,len(str)-1; i<len(runes)/2; i,j=i+1,j-1{
		runes[i],runes[j] = str[j],str[i]
	}
	return strings(runes)
}

HJ13 句子逆序

一遍过哈哈哈哈,开心

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	var input string
	scanner := bufio.NewScanner(os.Stdin)
	for scanner.Scan() {
		input = scanner.Text()
		words := strings.Split(input, " ")
		for i, j := 0, len(words)-1; i < len(words)/2; i, j = i+1, j-1 {
			words[i], words[j] = words[j], words[i]
		}
		for _, word := range words {
			fmt.Printf("%s ", word)
		}
	}
}

HJ14 字符串排序

package main

import (
	"bufio"
	"fmt"
	"os"
    "sort"
)

func main() {
   inputs:=[]string{}
   scanner:=bufio.NewScanner(os.Stdin)
   scanner.Scan()
   for scanner.Scan(){
    word:=scanner.Text()
    inputs = append(inputs, word)
   }
   sort.Strings(inputs)
   for _,word:=range inputs{
    fmt.Println(word)
   }
}

HJ15 求int型正整数在内存中存储时1的个数

int 类型在计算机中是按照二进制直接存储的。无论是在内存中还是在寄存器中,整数都是以二进制形式表示的

package main

import (
	"fmt"
)

func countBits(num int) int {
	count := 0
	for num != 0 {
		count += num & 1
		num >>= 1
	}
	return count
}

func main() {
	num := 0
	fmt.Scan(&num)
	fmt.Println(countBits(num))
}

HJ16 购物单

HJ33 整数与IP地址间的转换

涉及到了字符串和数字的转化、进制的转化、位运算

数字string转成int:strconv.Atoi()

数字int转成string:输出最终结果用fmt.Printf();存储为string变量:fmt.Springtf()strconv.Itoa()

package main

import (
	"fmt"
	"strconv"
	"strings"
)

func main() {
	var ipstring string
	var ipint int64
	fmt.Scanf("%s", &ipstring)
	fmt.Scanf("%d", &ipint)

	// IP地址转整数
	ip := strings.Split(ipstring, ".")
	var result int64
	for _, num := range ip {
		num_int, _ := strconv.Atoi(num)
		result = result<<8 | int64(num_int)
	}
	fmt.Println(result)

	// 整数转IP地址
	var ipParts [4]int
	for i := 0; i < 4; i++ {
		ipParts[3-i] = int(ipint & 0xFF)
		ipint >>= 8
	}
	fmt.Printf("%d.%d.%d.%d\n", ipParts[0], ipParts[1], ipParts[2], ipParts[3])
}