ads1_2021/code/golang/pkg/algorithms/stacks/next_greater_element/next_greater_element.go

101 lines
2.9 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()
S := stacks.CREATE()
S.INIT()
for i := 0; i < len(L); i++ {
logging.Debug("Stack S | %v", S)
logging.Debug("Nächstes List-Element L[%v] = %v betrachten", i, L[i])
nextElement := L[i]
logging.Debug("Alle top Elemente vom Stack, die < nextElement sind, mit L[i] paaren")
// Führe aus, bis top Element >= nextElement oder Stack leer ist.
for !S.EMPTY() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
element := S.TOP()
if element < nextElement {
logging.Debug("Stack S | %v; top Element > nextElement; ==> pop und Paar zum Output hinzufügen", S)
// falls top Element < next Element, zum Output hinzufügen und vom Stack
addToOutput(element, nextElement)
S.POP()
metrics.AddMovesCost()
logging.Debug("Stack S | %v", S)
} else if element > nextElement {
// falls top Element > next Element, auf Stack lassen und Schleife abbrechen.
break
} else {
// falls top Element == next Element, vom Stack entfernen und Schleife abbrechen.
S.POP()
metrics.AddMovesCost()
break
}
}
logging.Debug("L[%v] auf Stack legen", i)
S.PUSH(nextElement)
metrics.AddMovesCost()
}
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() { // ACHTUNG: schreibe 'while' im Pseudocode, denn dies ist eine while-Schleife in golang
logging.Debug("Stack S | %v", S)
element := S.TOP()
S.POP()
metrics.AddMovesCost()
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
}