Created
April 3, 2018 05:50
-
-
Save dfer/ba2c6f6a46fb8d3b71d54910a3ad1c59 to your computer and use it in GitHub Desktop.
Test work
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "encoding/csv" | |
| "fmt" | |
| "os" | |
| "io" | |
| s "strings" | |
| "strconv" | |
| "runtime" | |
| "github.com/julienschmidt/httprouter" | |
| "net/http" | |
| "time" | |
| ) | |
| var next_head = map[int32][2]int32{} // Индексы 0-next, 0-head | |
| func Makeset(x int32){ | |
| _, ok := next_head[x] | |
| if ok == false { | |
| next_head[x] = [2]int32{x, x} | |
| } | |
| } | |
| func Union(x, y int32){ | |
| _, ok_x := next_head[x] | |
| _, ok_y := next_head[y] | |
| if ok_x == true && ok_y == true && x != y { | |
| // Находим истинные head у X и Y | |
| // Если у нас неактуальные значения в head, то они перезапишутся с шагом 1 | |
| for next_head[x][1] != next_head[next_head[x][1]][1] { | |
| next_head[x] = [2]int32{next_head[x][0], next_head[next_head[x][1]][1]} | |
| } | |
| for next_head[y][1] != next_head[next_head[y][1]][1] { | |
| next_head[y] = [2]int32{next_head[y][0], next_head[next_head[y][1]][1]} | |
| } | |
| // Это разные циклические списки. Их можно объединять | |
| if next_head[x][1] != next_head[y][1] { | |
| // Ключевое изменение | |
| next_head[next_head[y][1]] = [2]int32{next_head[next_head[y][1]][0], x} | |
| temp := next_head[x][0] | |
| next_head[x] = [2]int32{next_head[y][0], next_head[x][1]} | |
| next_head[y] = [2]int32{temp, x} | |
| } | |
| } | |
| } | |
| // Получаем массив всех элементов входящих в множество с указанным элементом | |
| func All(x int32) []int32 { | |
| result := make([]int32, 0) | |
| _, ok_x := next_head[x] | |
| if ok_x == true { | |
| x_start := x | |
| result = append(result, x) | |
| x = next_head[x][0] | |
| for x != x_start { | |
| result = append(result, x) | |
| x = next_head[x][0] | |
| } | |
| } | |
| fmt.Println(result) | |
| return result | |
| } | |
| // Сохраняем массив с элементами в csv-файл | |
| func SaveAllTXT(x int32) { | |
| // Надо преобразовать int32 в int. А потом уже int преобразовывать в строку | |
| file, err := os.Create("public/"+strconv.Itoa(int(x))+".txt") | |
| if err != nil { | |
| fmt.Println(err) | |
| os.Exit(1) | |
| } | |
| defer file.Close() | |
| result := All(x) | |
| for _, value := range result { | |
| fmt.Fprintln(file, value) | |
| } | |
| } | |
| func Addstring(str string) { | |
| ar := s.Split(str, "|") | |
| ar_len := len(ar) - 1 | |
| if ar_len == 0 { | |
| temp, _ := strconv.Atoi(ar[0]) | |
| x := int32(temp) | |
| Makeset(x) | |
| } else { | |
| i := 0 | |
| for i < ar_len { | |
| temp, _ := strconv.Atoi(ar[i]) | |
| x := int32(temp) | |
| temp, _ = strconv.Atoi(ar[i+1]) | |
| y := int32(temp) | |
| Makeset(x) | |
| Makeset(y) | |
| Union(x, y) | |
| i += 1 | |
| } | |
| } | |
| } | |
| // Загружаем данные из файла при запуске программы | |
| func init() { | |
| fmt.Println("Start load db file") | |
| csvfile, err := os.Open("db") | |
| //csvfile, err := os.Open("redis_new.csv") | |
| if err != nil { | |
| fmt.Println(err) | |
| return | |
| } | |
| defer csvfile.Close() | |
| reader := csv.NewReader(csvfile) | |
| reader.FieldsPerRecord = -1 | |
| count := 0 | |
| // Построчное чтение файла | |
| for { | |
| line, err := reader.Read() | |
| if err == io.EOF { | |
| break | |
| } | |
| if err != nil { | |
| fmt.Println(err) | |
| os.Exit(1) | |
| } | |
| Addstring(line[2]) | |
| count += 1 // 297_596_361 - строк в файле | |
| if count % 1000 == 0 { | |
| fmt.Println(count/1000) | |
| } | |
| // Для отладки | |
| //if count == 5000000 { | |
| // break | |
| //} | |
| } | |
| fmt.Println("Load db file complete") | |
| } | |
| func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | |
| fmt.Fprint(w, "<html><body>Write ID here<br><br><form action=\"/get_info/\" method=\"get\"><input type=\"text\" name=\"id\"><input type=\"submit\"></form></body></html>") | |
| } | |
| func GetTreeNodes(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { | |
| t0 := time.Now() | |
| id_int64, _ := strconv.Atoi(r.FormValue("id")) | |
| id := int32(id_int64) | |
| SaveAllTXT(id) | |
| t1 := time.Now() | |
| fmt.Fprintf(w, "<html><body>Time: "+strconv.FormatFloat(float64(t1.Nanosecond()-t0.Nanosecond())/1E9, 'f', -1, 64)+" seconds.<br><br>You can download result <a href=\"/public/"+r.FormValue("id")+".txt\">here</a><br><br><a href=\"/\">Return to find form</a></body></html>") | |
| } | |
| func main() { | |
| runtime.GOMAXPROCS(2) | |
| router := httprouter.New() | |
| router.GET("/", Index) | |
| router.GET("/get_info", GetTreeNodes) | |
| router.ServeFiles("/public/*filepath", http.Dir("public")) | |
| http.ListenAndServe(":8080", router) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment