练习 12.1: word_letter_count.go

编写一个程序,从键盘读取输入。当用户输入 ‘S’ 的时候表示输入结束,这时程序输出 3 个数字:
i) 输入的字符的个数,包括空格,但不包括 ‘\r’ 和 ‘\n’
ii) 输入的单词的个数
iii) 输入的行数

// Q28_word_letter_count.go
package main

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

var nrchars, nrwords, nrlines int

func main() {
	nrchars, nrwords, nrlines = 0, 0, 0
	inputReader := bufio.NewReader(os.Stdin)
	fmt.Println("Please enter some input, type S to stop: ")
	for {
		input, err := inputReader.ReadString('\n')
		if err != nil {
			fmt.Printf("An error occurred: %s\n", err)
		}
		if input == "S\r\n" { // Windows, on Linux it is "S\n"
			fmt.Println("Here are the counts:")
			fmt.Printf("Number of characters: %d\n", nrchars)
			fmt.Printf("Number of words: %d\n", nrwords)
			fmt.Printf("Number of lines: %d\n", nrlines)
			os.Exit(0)
		}
		Counters(input)
	}
}

func Counters(input string) {
	nrchars += len(input) - 2 // -2 for \r\n
	nrwords += len(strings.Fields(input))
	nrlines++
}

编写一个简单的逆波兰式计算器,它接受用户输入的整型数(最大值 999999)和运算符 +、-、*、/。

输入的格式为:number1 ENTER number2 ENTER operator ENTER --> 显示结果
当用户输入字符 ‘q’ 时,程序结束

package main

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

type Stack struct {
	items []any
}

func NewStack() *Stack {
	return &Stack{}
}
func (s *Stack) Push(item any) {
	s.items = append(s.items, item)
}
func (s *Stack) Pop() any {
	if len(s.items) == 0 {
		return nil
	}
	item := s.items[len(s.items)-1]
	s.items = s.items[:len(s.items)-1]
	return item
}
func (s *Stack) Size() int {
	return len(s.items)
}
func (s *Stack) IsEmpty() bool {
	return s.Size() == 0
}
func (s *Stack) Peek() any {
	if len(s.items) == 0 {
		return nil
	}
	return s.items[len(s.items)-1]
}
func (s *Stack) String() string {
	var str3 string
	for _, item := range s.items {
		str3 = str3 + strconv.Itoa(item.(int)) + " "
	}
	return str3
}
func main() {
	stack := NewStack()
	inputScanner := bufio.NewScanner(os.Stdin)
	fmt.Println("Enter the expression (number1 ENTER number2 ENTER operator ENTER), or 'q' to quit:")
	for inputScanner.Scan() {
		input := inputScanner.Text()
		if input == "q" {
			break
		}
		inputs := strings.Fields(input)
		if len(inputs) != 3 {
			fmt.Println("Wrong input")
			continue
		}
		number1, err := strconv.Atoi(inputs[0])
		if err != nil {
			fmt.Println("Invalid number:", inputs[0])
			continue
		}
		number2, err := strconv.Atoi(inputs[1])
		if err != nil {
			fmt.Println("Invalid number:", inputs[1])
			continue
		}
		stack.Push(number1)
		stack.Push(number2)
		operator := inputs[2]
		switch operator {
		case "+":
			num1 := stack.Pop().(int)
			num2 := stack.Pop().(int)
			stack.Push(num1 + num2)
		case "-":
			num1 := stack.Pop().(int)
			num2 := stack.Pop().(int)
			stack.Push(num1 - num2)
		case "*":
			num1 := stack.Pop().(int)
			num2 := stack.Pop().(int)
			stack.Push(num1 * num2)
		case "/":
			num1 := stack.Pop().(int)
			num2 := stack.Pop().(int)
			stack.Push(num1 / num2)
		default:
			continue
		}
	}
	fmt.Println(stack)
}