如何改善我的功能,如果2位数字四舍五入到最接近的10,如果3位数字等则到100

时间:2018-12-11 19:27:51

标签: algorithm go

我正在绘制条形图,但遇到了一个棘手的问题。如何根据给定系列的最大值以编程方式设置y轴标签的最大值。因此,如果您有一个值为7的条,则可能希望y轴上升到10

我的方法并不理想,但可以这样工作:

  • 获取一个数字,例如829
  • 计算位数(3)
  • 使用循环转换为0s(“ 000”)字符串
  • 在字符串的开头添加1,然后转换为浮点数(1000)
  • 找出差异(1000-829 = 171)
  • 获取差值的第一位数字(1),然后将其添加到浮点数的第一位数字,其余设置为零(“ 900”),然后转换为数字(900)

这意味着725的y轴最大标签数为800,而829的900则为900

我的代码有效,但是我觉得这有点笨拙

我必须为大数编码。例如,如果我要查找的最大值的浮点数> 10000,则取前两位数字,然后加上1000。如果> 100,000,则添加10,000

我该如何改进?我有点卡住,我转换成字符串的想法还对吗?!

完整代码在这里:

package main

import (
    "fmt"
    "strconv"
)

func main() {

    myFloat := 899175.0

    x := getMaxYAxisValueForChart(myFloat)
    fmt.Println("The number to find the maximum value for is: ", myFloat)
    fmt.Println("This should be the max value for the y axis: ", x)
}

func getMaxYAxisValueForChart(float float64) (YAxisMaximum float64) {
    //Convert to string with no decimals
    floatAsString := fmt.Sprintf("%.f", float)

    //Get length of the string float
    floatAsStringLength := len(floatAsString)

    //For each digit in the string, make a zero-string
    stringPowerTen := "0"
    for i := 1; i < floatAsStringLength; i++ {
        stringPowerTen += "0"
    }

    //Add a 1 to the 0 string to get the difference from the float
    stringPowerTenWithOne := "1" + stringPowerTen

    //Convert the number string to a float
    convertStringPowerTenToFloat := ConvertStringsToFloat(stringPowerTenWithOne)

    //Get the difference from the denominator from the numerator
    difference := convertStringPowerTenToFloat - float

    //We want to isolate the first digit to check how far the float is (100 is far from 1000) and then correct if so
    floatAsStringDifference := fmt.Sprintf("%.f", difference)
    runes := []rune(floatAsStringDifference)
    floatAsStringDifferenceFirstDigit := string(runes[0])

    //For the denominator we want to take away the difference that is rounded to the nearest ten, hundred etc
    runes = []rune(stringPowerTen)
    differenceLastDigitsAsString := ""
    if difference < 10 {
        differenceLastDigitsAsString = "1"
    } else if difference < 30 && difference < 100 {
        differenceLastDigitsAsString = "0"
    } else {
        differenceLastDigitsAsString = floatAsStringDifferenceFirstDigit + string(runes[1:])
    }

    //Convert the number difference string from total to a float
    convertDifferenceStringPowerTenToFloat := ConvertStringsToFloat(differenceLastDigitsAsString)

    YAxisMaximum = convertStringPowerTenToFloat - convertDifferenceStringPowerTenToFloat

    //If float is less than 10,0000
    if float < 10000 && (YAxisMaximum-float >= 500) {
        YAxisMaximum = YAxisMaximum - 500
    }

    if float < 10000 && (YAxisMaximum-float < 500) {
        YAxisMaximum = YAxisMaximum
    }

    //If number bigger than 10,000 then get the nearest 1,000
    if float > 10000 {

        runes = []rune(floatAsString)
        floatAsString = string(runes[0:2])
        runes = []rune(stringPowerTen)
        stringPowerTen = string(runes[2:])
        runes = []rune(stringPowerTenWithOne)
        stringPowerTenWithOne = string(runes[0:(len(stringPowerTenWithOne) - 2)])

        YAxisMaximum = ConvertStringsToFloat(floatAsString+stringPowerTen) + ConvertStringsToFloat(stringPowerTenWithOne)
    }

    if float > 10000 {

        runes = []rune(floatAsString)
        floatAsString = string(runes[0:2])
        runes = []rune(stringPowerTen)
        stringPowerTen = string(runes[:])
        runes = []rune(stringPowerTenWithOne)
        stringPowerTenWithOne = string(runes[0:(len(stringPowerTenWithOne))])

        YAxisMaximum = ConvertStringsToFloat(floatAsString+stringPowerTen) + ConvertStringsToFloat(stringPowerTenWithOne)
    }

    return YAxisMaximum
}

func ConvertStringsToFloat(stringToConvert string) (floatOutput float64) {
    floatOutput, Error := strconv.ParseFloat(stringToConvert, 64)
    if Error != nil {
        fmt.Println(Error)
    }

    return floatOutput
}

以下是基于Matt Timmermans回答的解决方案,但已转换为可在Go中使用:

func testing(float float64) (YAxisMaximum float64) {
    place := 1.0
    for float >= place*10.0 {
        place *= 10.0
    }
    return math.Ceil(float/place) * place
}

4 个答案:

答案 0 :(得分:1)

哇,这是一个非常复杂的过程。如果数量不多,我将采用这种方式。我不知道去,所以我将猜测如何用该语言编写它:

func getMaxYAxisValueForChart(float float64) {

    place := 1.0;
    while float >= place*10.0 {
        place *= 10.0;
    }
    return math.Ceil(float/place) * place;
}

答案 1 :(得分:1)

取字符串的长度,并计算该长度的幂为10

或者...更好地采用对数为10,取整数部分,加1,然后将其返回10的幂:)

    import (
        "fmt"
        "math"
    )

    //func PowerScale(x int) int64{
    //   return int64(math.Pow(10,float64(len((fmt.Sprintf("%d",x))))))
    //}

    func PowerScale(x int) int64 {
     return int64(math.Pow(10,float64(int(math.Log10(float64(x))+1))))
}

    func main() {
        fmt.Println(PowerScale(829))
        fmt.Println(PowerScale(7))
    }

答案 2 :(得分:1)

您可以使用Math.Log10获取数字的大小

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.30,random_state=100)

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(X_train)


xgb = xgboost.XGBRegressor(colsample_bytree=0.7,
                 gamma=0,                 
                 learning_rate=0.01,
                 max_depth=1,
                 min_child_weight=1.5,
                 n_estimators=100000,                                                                    
                 reg_alpha=0.75,
                 reg_lambda=0.45,
                 subsample=0.8,
                 seed=1000) 

使用它可以将数字向下划分,计算上限,然后再向上扩展。

没有字符串,没有while循环。

答案 3 :(得分:1)

由于829是int或可以转换为纯整数解决方案:

func getMaxYAxisValueForChart(int int64) {
    base := 10;
    while int > base*10 {
        base := 10 * base; 
    }
    return int + (base - int) % base;
}