找出重复行

1、

package main

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

func main()  {
	counts := make(map[string]int)
	input := bufio.NewScanner(os.Stdin)
	for input.Scan() {
		counts[input.Text()]++
	}
	for line, n := range counts {
		if n > 1 {
			fmt.Printf("%d\t%s\n", n, line)
		}
	}
}

map 存储一个键/值对集合,并且提供常量时间的操作来存储、获取或测试集合中的某个元素。键可以是其值能够进行相等(==)比较的任意类型,字符串是最常见的例子;值可以是任意类型。为了输出结果,我们使用基于 range 的 for 循环,每次迭代输出两个结果,map 里面一个元素对应的键和值。map 里面的键的迭代顺序不是固定的,通常是随机的,每次运行都不一致。
使用bufio 包,可以简便和高效地处理输入和输出。Scanner 可以读入输入,以行或者单词为单位断开,这是已行为单位的输入内容的最简单方式。
每一次调用 input.Scan() 读取下一行,并且将结尾的换行符去掉;通过调用 input.Text() 来获取读到的内容。Scan 函数在读到新行的时候返回 true ,在没有更多内容的是否返回 false。
Printf 函数有超过10个这样的转义字符,Go 程序员称为 verb。如下
verb 描述
%d 十进制整数
%x,%o,%b 十六进制、八进制、二进制整数
%f,%g,%e 浮点数,如:3.1415926
%t 布尔型,true 或 false
%c 字符(Unicode 码点)
%s 字符串
%q 带引号字符串(如 “abc”)或者字符(‘c’)
%v 内置格式的任何值
%T 任何值的类型
%% 百分号本身(无操作数)
诸如 log.Printf 和 fmt.Errorf 之类的格式化函数已 f 结尾,使用和 fmt.Printf 相同的格式化规则;而那些以 ln 结尾的函数(如 Println) 则使用 %v 的方式来格式化参数,并在最后追加换行符。
2、下面的程序是从文件列表中进行读取,并使用 os.Open 函数来逐个打开。

package main

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

func main()  {
	counters := make(map[string]int)
	files := os.Args[1:]
	if len(files) == 0 {
		counteLines(os.Stdin, counters)
	} else {
		for _, arg := range files {
			f, err := os.Open(arg)
			if err != nil {
				fmt.Println(os.Stderr, "dump2: %v\n", err)
				continue
			}
			counteLines(f, counters)
			f.Close()
		}
	}
	for line, n := range counters {
		if n > 1 {
			fmt.Printf("%d\t%s\n", n, line)
		}
	}
}

func counteLines(f *os.File, counts map[string]int)  {
	intput := bufio.NewScanner(f)
	for intput.Scan() {
		counts[intput.Text()]++
	}

}

在此代码中, map 是一个使用 make 创建的数据结构的引用。当一个 map 被传递给一个函数时,函数接收到这个引用的副本,所以被调用函数中对于 map 数据结构中的改变对函数调用者使用的 map 引用也是可见的。
3、

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strings"
)

func main()  {
	counts := make(map[string]int)
	for _, filename := range os.Args[1:] {
		data, err := ioutil.ReadFile(filename)
		if err != nil {
			fmt.Fprint(os.Stderr, "dup3: %v\n", err)
			continue
		}
		for _, line := range strings.Split(string(data), "\n") {
			counts[line]++
		}
	}

	for line, n := range counts{
		if n > 1 {
			fmt.Printf("%d\t%s\n", n, line)
		}
	}

}

上面的程序中,引入一个 ReadFile 函数(从 io/ioutil包),它读取整个命名文件的内容,还引入一个 strings.Split 函数,它将字符串分割为一个由字符组成的 slice。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值