Golang for loop with 2 variables equivalent? - go

I am trying to understand golang's syntax in doc but some things are hard to understand even they explain it.
For example:
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
I translated it to raw code:
func reverseString2(str string) string {
var array = []rune(str)
for i := 0; i < len(str)/2; i++ {
for j := len(str) - 1; ???? ; j-- {
// ---
}
}
return string(array)
}
my problem is that in the first one for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1, j does not seems to have a condition so in my code I dont know how to solve it.

This is another way that is easier to read and leads to the same result.
The only difference is that the scope of variable j has become different.
func Reverse(s string) string {
r := []rune(s)
j := len(r) - 1
for i := 0; i < len(r)/2; i++ {
r[i], r[j] = r[j], r[i]
j--
}
return string(r)
}

Related

panic: runtime error: index out of range [-1]

when I try to solve the leetcode problem of 118. Pascal's Triangle https://leetcode.com/problems/pascals-triangle/
it occured strange bug. Below the code can pass OJ.
func generate(numRows int) [][]int {
res := [][]int{}
for i := 0; i < numRows; i++ {
row := []int{}
for j := 0; j < i+1; j++ {
if j == 0 || j == i {
row = append(row, 1)
} else if i > 1 {
row = append(row, res[i-1][j-1] + res[i-1][j])
}
}
res = append(res, row)
}
return res
}
But the code I write like this and it occur panic, but the basic logic is same.
func generate(numRows int) [][]int {
res := [][]int{}
for i := 0; i < numRows; i++ {
row := []int{}
for j := 0; j < i+1; j++ {
if j == 0 || j == i {
row = append(row, 1)
}
if i > 1 {
row = append(row, res[i-1][j-1] + res[i-1][j])
}
}
res = append(res, row)
}
return res
}
I used if else if structure, it works fine, but I use 2 if condition judgment error.
In fact, their logic is the same, but why the error? I would be grateful if you could solve this problem. Good lcuk for you!
The problem is that you use 2 if conditions in the second version, while in the first version you have an if else.
but the basic logic is same
No, the logic is not the same. The result is that you try to do j-1 when j is 0.
If you have 2 if conditions like this, the program will enter both blocks individually if their respective condition is met.
if j == 0 || j == i {
row = append(row, 1)
}
// if j is 0 you still enter this block as long as i > 1
if i > 1 {
row = append(row, res[i-1][j-1] + res[i-1][j])
}
You could use continue to skip this section, if the first if is met.
if j == 0 || j == i {
row = append(row, 1)
// continue with the next iteration
continue
}
if i > 1 {
row = append(row, res[i-1][j-1] + res[i-1][j])
}
That said, using the if else in the first version of your code seems reasonable. I am not sure why you would want to change it.

golang deadlock error with waitgroups but no channels

im new to go. i have this project it's about matrices and their operations. i am supposed to use goroutine in my multiply function.(also disclaimer:this is not my code, its a group project im supposed to add the goroutine to the function)
i've searched around and seen this way(the way that i used) in different sites.however i get a fatal error: all the goroutines are asleep.deadlock!
or it just takes way too long for the code to run.
func (M Matrix) Multiply(N Matrix) Matrix {
var ans = BuildZeroMatrix(len(M), len(N[0]))
var wg sync.WaitGroup
wg.Add(len(M)*len(N[0])*len(N))
for i := 0; i < len(M); i++ {
for j := 0; j < len(N[0]); j++ {
for k := 0; k < len(N); k++ {
wg.Add(1)
go func(j int, i int, k int) {
ans[i][j] += M[i][k] * N[k][j]
defer wg.Done()
}(j, i, k)
}
}
}
go func(){
wg.Wait()
}()
return ans
}
this is the multiply function.
type Matrix [][]float64
this is Matrix.
func BuildZeroMatrix(Row int, Col int) Matrix {
var temp [][]float64
for i := 0; i < Row; i++ {
var tmp []float64
for j := 0; j < Col; j++ {
tmp = append(tmp, 0)
}
temp = append(temp, tmp)
}
M, _ := BuildMatrix(Row, Col, temp)
return M
}
and this is the buildzeromatrix function.
i give the function 2 500*500 matrices and it takes about 10 seconds to run or it gives the fatal error.
every post i found on this problem had channels in them and their problem was with the channel.however i dont have any.
Just pointing out the mistakes in this snippet. Please check the inline comments.
func (M Matrix) Multiply(N Matrix) Matrix {
var ans = BuildZeroMatrix(len(M), len(N[0]))
var wg sync.WaitGroup
wg.Add(len(M)*len(N[0])*len(N)) // This is unnecessary. You are already adding the goroutine inside the k loop.
for i := 0; i < len(M); i++ {
for j := 0; j < len(N[0]); j++ {
for k := 0; k < len(N); k++ {
wg.Add(1)
go func(j int, i int, k int) {
ans[i][j] += M[i][k] * N[k][j] // This is data race area. Multiple goroutines will try to write to the same address. You will need a lock here.
defer wg.Done()
}(j, i, k)
}
}
}
go func(){
wg.Wait() // Wait()ing for goroutines to be completed should not be done inside a goroutine. Because here you don't wait for this goroutine to be done.
}()
return ans
}
UPDATED: Pls check the sample code
package main
import (
"fmt"
"sync"
)
type Matrix [][]float64
func (M Matrix) Multiply(N Matrix) Matrix {
var ans = BuildZeroMatrix(len(M), len(N[0]))
var wg sync.WaitGroup
var mx sync.Mutex
for i := 0; i < len(M); i++ {
for j := 0; j < len(N[0]); j++ {
for k := 0; k < len(N); k++ {
wg.Add(1)
go func(j int, i int, k int) {
defer wg.Done()
mx.Lock()
ans[i][j] += M[i][k] * N[k][j]
mx.Unlock()
}(j, i, k)
}
}
}
wg.Wait()
return ans
}
func BuildZeroMatrix(Row int, Col int) Matrix {
var temp [][]float64
for i := 0; i < Row; i++ {
var tmp []float64
for j := 0; j < Col; j++ {
tmp = append(tmp, 0)
}
temp = append(temp, tmp)
}
return temp
}
func main() {
var m, n Matrix
// T1:
m = Matrix{[]float64{1, 1, 1}, []float64{1, 1, 1}, []float64{1, 1, 1}}
n = Matrix{[]float64{1, 1, 1}, []float64{1, 1, 1}, []float64{1, 1, 1}}
fmt.Printf("%v", m.Multiply(n))
// T2:
m = Matrix{[]float64{1, 1, 1}, []float64{1, 1, 1}, []float64{1, 1, 1}}
n = Matrix{[]float64{1, 1}, []float64{1, 1}, []float64{1, 1}}
fmt.Printf("\n%v", m.Multiply(n))
}

How to solve Spiral Matrix in go

https://leetcode.com/problems/spiral-matrix/
golang implement.
the result as follow:
Run Code Status: Runtime Error
Run Code Result: ×
Your input
[]
Your answer
Expected answer
[]
Show Diff
why [] is the test case ,it's just a one-dimensional slice ?
my code is :
func sprial(begin_r, begin_c, row, col int, matrix [][]int) []int {
s := make([]int, col*row, col*row+10)
k := 0
if row == 1 && col == 1 {
s[k] = matrix[begin_r][begin_c]
return s
} else if row == 1 {
return matrix[begin_r][begin_c : col-1]
} else if col == 1 {
return matrix[begin_r : row-1][begin_c]
} else {
for i := begin_c; i < col; i++ {
s[k] = matrix[begin_r][i]
k++
}
for i := begin_r + 1; i < row; i++ {
s[k] = matrix[i][col-1]
k++
}
for i := col - 2; i >= begin_c; i-- {
s[k] = matrix[row-1][i]
k++
}
for i := row - 2; i >= begin_r+1; i-- {
s[k] = matrix[i][begin_c]
k++
}
return s[:k-1]
}
}
func spiralOrder(matrix [][]int) []int {
m := len(matrix)
n := len(matrix[0])
i := 0
j := 0
// var rS []int
k := 0
//s1 := make([]int, m*n, m*n)
var s1 = []int{}
for {
if m <= 0 || n <= 0 {
break
}
s := sprial(i, j, m, n, matrix)
if k == 0 {
s1 = s
} else {
s1 = append(s1, s...)
}
i++
j++
m -= 2
n -= 2
k++
}
return s1
}
func spiralOrder(matrix [][]int) []int {
if len(matrix) == 0 || len(matrix[0]) == 0 {
return nil
}
m, n := len(matrix), len(matrix[0])
next := nextFunc(m, n)
res := make([]int, m*n)
for i := range res {
x, y := next()
res[i] = matrix[x][y]
}
return res
}
func nextFunc(m, n int) func() (int, int) {
top, down := 0, m-1
left, right := 0, n-1
x, y := 0, -1
dx, dy := 0, 1
return func() (int, int) {
x += dx
y += dy
switch {
case y+dy > right:
top++
dx, dy = 1, 0
case x+dx > down:
right--
dx, dy = 0, -1
case y+dy < left:
down--
dx, dy = -1, 0
case x+dx < top:
left++
dx, dy = 0, 1
}
return x, y
}
}
Source: https://github.com/aQuaYi/LeetCode-in-Go/blob/master/Algorithms/0054.spiral-matrix/spiral-matrix.go
This repository has most of the solutions to LeetCode problems in a very optimal manner. Please do take a look. Hope it helps.

How to find out diagonal difference in go programming?

My code:
package main
import "fmt"
func main() {
var n int
fmt.Scan(&n)
s := make([][]int, n)
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
fmt.Scanf("%d %d", &s[i][j])
}
}
s1 := 0
s2 := 0
for i := 0; i < n; i++ {
for j := 0; j < n; j++ {
if i == j {
s1 += s[i][j]
}
if i+j == n-1 {
s2 += s[i][j]
}
}
fmt.Println(s1 - s2)
}
}
Output:
panic: runtime error: index out of range
I tried but get panic. I want to know proper solution to this problem.
This line:
s := make([][]int, n)
Creates a slice of slices, a slice whose elements are of type []int. It creates a slice with n elements, but the elements of the outer slice are initialized with the zero value of the element type, and zero value of type []int is nil (just like for any slice type).
You get index out of range panic because any element of the outer slice s has zero length (because they are not initialized to a non-nil slice), so s[i][j] panics for any j value.
If you want to assign elements to the "inner" slices, you also have to initialize them:
for i := 0; i < n; i++ {
s[i] = make([]int, n) // YOU ARE MISSING THIS LINE
for j := 0; j < n; j++ {
fmt.Scanf("%d %d", &s[i][j])
}
}

Go : longest common subsequence to print result array

I have implemented Longest Common Subsequence algorithm and getting the right answer for longest but cannot figure out the way to print out what makes up the longest common subsequence.
That is, I succeeded to get the length of longest commond subsequence array but I want to print out the longest subsequence.
The Playground for this code is here
http://play.golang.org/p/0sKb_OARnf
/*
X = BDCABA
Y = ABCBDAB => Longest Comman Subsequence is B C B
Dynamic Programming method : O ( n )
*/
package main
import "fmt"
func Max(more ...int) int {
max_num := more[0]
for _, elem := range more {
if max_num < elem {
max_num = elem
}
}
return max_num
}
func Longest(str1, str2 string) int {
len1 := len(str1)
len2 := len(str2)
//in C++,
//int tab[m + 1][n + 1];
//tab := make([][100]int, len1+1)
tab := make([][]int, len1+1)
for i := range tab {
tab[i] = make([]int, len2+1)
}
i, j := 0, 0
for i = 0; i <= len1; i++ {
for j = 0; j <= len2; j++ {
if i == 0 || j == 0 {
tab[i][j] = 0
} else if str1[i-1] == str2[j-1] {
tab[i][j] = tab[i-1][j-1] + 1
if i < len1 {
fmt.Printf("%c", str1[i])
}
} else {
tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
}
}
}
fmt.Println()
return tab[len1][len2]
}
func main() {
str1 := "AGGTABTABTABTAB"
str2 := "GXTXAYBTABTABTAB"
fmt.Println(Longest(str1, str2))
//Actual Longest Common Subsequence: GTABTABTABTAB
//GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
//13
str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
fmt.Println(Longest(str3, str4))
//Actual Longest Common Subsequence: ?
//GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
//14
}
When I try to print out the subsequence when the tab gets updates, the outcome is duplicate.
I want to print out something like "GTABTABTABTAB" for the str1 and str2
Thanks in advance.
EDIT: It seems that I jumped the gun on answering this. On the Wikipedia page for Longest Common Subsequnce they give the pseudocode for printing out the LCS once it has been calculated. I'll put an implementation in go up here as soon as I have time for it.
Old invalid answer
You are forgetting to move along from a character once you have registered it as part of the subsequence.
The code below should work. Look at the two lines right after the fmt.Printf("%c", srt1[i]) line.
playground link
/*
X = BDCABA
Y = ABCBDAB => Longest Comman Subsequence is B C B
Dynamic Programming method : O ( n )
*/
package main
import "fmt"
func Max(more ...int) int {
max_num := more[0]
for _, elem := range more {
if max_num < elem {
max_num = elem
}
}
return max_num
}
func Longest(str1, str2 string) int {
len1 := len(str1)
len2 := len(str2)
//in C++,
//int tab[m + 1][n + 1];
//tab := make([][100]int, len1+1)
tab := make([][]int, len1+1)
for i := range tab {
tab[i] = make([]int, len2+1)
}
i, j := 0, 0
for i = 0; i <= len1; i++ {
for j = 0; j <= len2; j++ {
if i == 0 || j == 0 {
tab[i][j] = 0
} else if str1[i-1] == str2[j-1] {
tab[i][j] = tab[i-1][j-1] + 1
if i < len1 {
fmt.Printf("%c", str1[i])
//Move on the the next character in both sequences
i++
j++
}
} else {
tab[i][j] = Max(tab[i-1][j], tab[i][j-1])
}
}
}
fmt.Println()
return tab[len1][len2]
}
func main() {
str1 := "AGGTABTABTABTAB"
str2 := "GXTXAYBTABTABTAB"
fmt.Println(Longest(str1, str2))
//Actual Longest Common Subsequence: GTABTABTABTAB
//GGGGGTAAAABBBBTTTTAAAABBBBTTTTAAAABBBBTTTTAAAABBBB
//13
str3 := "AGGTABGHSRCBYJSVDWFVDVSBCBVDWFDWVV"
str4 := "GXTXAYBRGDVCBDVCCXVXCWQRVCBDJXCVQSQQ"
fmt.Println(Longest(str3, str4))
//Actual Longest Common Subsequence: ?
//GGGTTABGGGHHRCCBBBBBBYYYJSVDDDDDWWWFDDDDDVVVSSSSSBCCCBBBBBBVVVDDDDDWWWFWWWVVVVVV
//14
}

Resources