108 lines
2.6 KiB
Go
108 lines
2.6 KiB
Go
package next_greater_element
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* IMPORTS
|
|
* ---------------------------------------------------------------- */
|
|
|
|
import (
|
|
"ads/internal/core/logging"
|
|
"ads/internal/core/metrics"
|
|
"ads/pkg/data_structures/stacks"
|
|
)
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* GLOBAL VARIABLES/CONSTANTS
|
|
* ---------------------------------------------------------------- */
|
|
|
|
var _output_list [][2]int
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* ALGORITHM next greater element
|
|
* ---------------------------------------------------------------- */
|
|
|
|
/*
|
|
Inputs: L = Liste von Zahlen, x = Zahl.
|
|
|
|
Outputs: Liste von Paaren von Elementen und ihrem nächsten größeren Element
|
|
*/
|
|
func NextGreaterElement(L []int) [][2]int {
|
|
clearOutput()
|
|
if len(L) == 0 {
|
|
return output()
|
|
}
|
|
|
|
S := stacks.CREATE()
|
|
|
|
for i := 0; i < len(L); i++ {
|
|
logging.Debug("Lies Element L[%v] ein", i)
|
|
nextElement := L[i]
|
|
|
|
logging.Debug("Stack S | %v", S)
|
|
if !S.EMPTY() {
|
|
logging.Debug("Entferne alle top Elemente vom Stack bis >= nextElement")
|
|
element := S.TOP()
|
|
S.POP()
|
|
metrics.AddTimeCost()
|
|
/*
|
|
Entferne kleinere Elemente vom Stack
|
|
Aktuelles Element ist jeweils größerer rechter Partner
|
|
*/
|
|
for element < nextElement {
|
|
logging.Debug("Stack S | %v", S)
|
|
addToOutput(element, nextElement)
|
|
if S.EMPTY() {
|
|
break
|
|
}
|
|
element = S.TOP()
|
|
S.POP()
|
|
metrics.AddTimeCost()
|
|
}
|
|
|
|
// lege letztes Element zurück
|
|
if element > nextElement {
|
|
logging.Debug("Element >= nextElement zurücklegen")
|
|
S.PUSH(element)
|
|
metrics.AddTimeCost()
|
|
}
|
|
logging.Debug("Stack S | %v", S)
|
|
}
|
|
|
|
S.PUSH(nextElement)
|
|
metrics.AddTimeCost()
|
|
logging.Debug("L[%v] auf Stack legen", i)
|
|
logging.Debug("Stack S | %v", S)
|
|
}
|
|
|
|
// was übrig bleibt hat kein größeres Element
|
|
logging.Debug("Alles übrige auf Stack hat kein nächstes größeres Element")
|
|
for !S.EMPTY() {
|
|
metrics.AddTimeCost()
|
|
logging.Debug("Stack S | %v", S)
|
|
element := S.TOP()
|
|
S.POP()
|
|
addToOutput(element, -1)
|
|
}
|
|
logging.Debug("Stack S | %v", S)
|
|
|
|
return output()
|
|
}
|
|
|
|
/* ---------------------------------------------------------------- *
|
|
* AUXILIARY METHODS
|
|
* ---------------------------------------------------------------- */
|
|
|
|
func clearOutput() {
|
|
_output_list = [][2]int{}
|
|
}
|
|
|
|
func addToOutput(m int, n int) {
|
|
_output_list = append(_output_list, [2]int{m, n})
|
|
}
|
|
|
|
func output() [][2]int {
|
|
var output = make([][2]int, len(_output_list))
|
|
copy(output, _output_list)
|
|
clearOutput()
|
|
return output
|
|
}
|