-2

在某处陷入僵局。是什么原因造成的,应该如何解决?试图创造一个分子创造。函数 Make 将输入作为字符串:

func testMolecule() {
    water := New()
    water.Make("HOH")   // water.Make("OOHHHH")
    fmt.Println(water.Molecules())
    // Output: 1
}

函数应返回创建的分子数。分子应该有 1 个 O 分子和 2 个 H 分子。在创建所有分子之前不应完成生产功能。

import (
    "sync"
)

// Water structure holds the synchronization primitives and
// data required to solve the water molecule problem.
// moleculeCount holds the number of molecules formed so far.
// result string contains the sequence of "H" and "O".
// wg WaitGroup is used to wait for goroutine completion.
type Water struct {
    sync.Mutex
    wg            sync.WaitGroup
    cond          *sync.Cond
    moleculeCount int
    result        string
    assignedO     int
    assignedH     int
    finished      bool


}

// New initializes the water structure.
func New() *Water {
    water := &Water{
        moleculeCount: 0,
        result:        "",
        assignedO:     0,
        assignedH:     0,
        finished:      false,
    }
    water.cond = sync.NewCond(water)
    return water
}

// releaseOxygen produces one oxygen atom if no oxygen atom is already present.
// If an oxygen atom is already present, it will block until enough hydrogen
// atoms have been produced to consume the atoms necessary to produce water.
//
// The w.wg.Done() must be called to indicate the completion of the goroutine.
func (w *Water) releaseOxygen() {
    defer w.wg.Done()
    for {
        w.Lock()
        if w.assignedO == 0 {
            w.assignedO = 1

        }
        for !(w.assignedH == 2) {

            w.cond.Wait()
        }
        w.result = w.result + "O"
        w.cond.Broadcast()
        w.Unlock()
    }

}

// releaseHydrogen produces one hydrogen atom unless two hydrogen atoms are already present.
// If two hydrogen atoms are already present, it will block until another oxygen
// atom has been produced to consume the atoms necessary to produce water.
//
// The w.wg.Done() must be called to indicate the completion of the goroutine.
func (w *Water) releaseHydrogen() {
    defer w.wg.Done()
    for {
        w.Lock()
        if w.assignedH < 2 {
            w.assignedH = w.assignedH + 1

        }
        for !(w.assignedO == 1) && w.assignedH == 2 {
            w.cond.Wait()
        }
        w.result = w.result + "HH"
        w.cond.Broadcast()
        w.Unlock()
    }
}

// produceMolecule forms the water molecules.
func (w *Water) produceMolecule(done chan bool) {
    for {
        w.Lock()
        for w.assignedO == 1 && w.assignedH == 2 && !w.finished {
            w.cond.Wait()
        }
        if w.assignedO == 0 && w.assignedH == 0 && w.finished {
            w.Unlock()
            break
        }
        w.moleculeCount = w.moleculeCount + 1
        w.assignedH = 0
        w.assignedO = 0
        w.cond.Broadcast()
        w.Unlock()
    }

    done <- true
}

func (w *Water) finish() {
    w.Lock()
    w.finished = true
    w.cond.Broadcast()
    w.Unlock()

}

func (w *Water) Molecules() int {
    return w.moleculeCount
}

// Make returns a sequence of water molecules derived from the input of hydrogen and oxygen atoms.
func (w *Water) Make(input string) string {
    done := make(chan bool)
    go w.produceMolecule(done)
    for _, ch := range input {
        w.wg.Add(1)
        switch ch {
        case 'O':
            go w.releaseOxygen()
        case 'H':
            go w.releaseHydrogen()
        }
    }
    w.wg.Wait()
    w.finish()
    <-done
    return w.result
}
4

1 回答 1

0

函数应返回创建的分子数。分子应该有 1 个 O 分子和 2 个 H 分子。

您不需要任何同步或并发。只需计算 Os,Hs,并返回 O 的数量或 H 的一半数量中的较小者。

https://play.golang.org/p/3FaJDMi5ER7

我从上一个问题中知道您可能正在尝试构建某种模拟或模型,但我不了解您的目标。

于 2021-11-08T14:13:27.063 回答