簡體   English   中英

如何使用go識別給定號碼的匹配模式?

[英]How can I identify a matching pattern for a given number using go?

我正在嘗試確定給定電話號碼范圍的模式匹配,以用於Cisco Communications Manager平台。

本質上,“ X”與電話號碼中的數字0-9匹配,並且您可以使用[xy]表示法指定數字范圍。

給定電話號碼范圍01502221000-02072221149(包含150個號碼),這將創建並輸出兩種模式:020722210XX和020722211 [0-4] X

顯然,我希望它可以在提供的任何范圍內工作。 在給定數字范圍的情況下,我似乎無法理解如何生成這些模式。

任何想法將不勝感激。 非常感謝。

我相信我找到了一個不錯的算法可以為您解決這個問題。 如果其中的任何解釋不夠詳細,我會提前道歉,但其中很多都是直覺,很難解釋。

我從更簡單的案例開始,想出一種方法來從比較中獲得最少的模式。 對於我的示例,我將比較211234245245 經過一番思考,我得出結論,您需要采用較小數字到9的數字范圍,並處理較小數字中最低數字的特殊情況。 為了更詳細地說明,在數字211234 ,理想的情況是將最后一個數字表示為X但是我們只能在數字可能為[0-9]的情況下執行此操作,在此示例中,唯一的情況是當十位數是3時, [0-9]使用[0-9] ,因為我們的下限是4 然后,當我們朝着最高有效數字前進時,此邏輯將沿數字的其余部分向上傳播。 因此,對於下一種情況下的十位數,我們基於前面的4實例有一個下限,因為當我們特別允許3時,我們正在處理這種情況。 因此,對於我們的十位數范圍,我們最終得到4-9因為下一位數字不會限制我們的范圍。

實際上,直到最高有效位數受要比較的數字之間的范圍所限制,我們才受到限制。 手工解決了一些問題之后,在數字與數字明顯分開的情況下,我注意到X的金字塔的一種模式:

compare: 211234
to:      245245


21123[4-9]
2112[4-9]X
211[3-9]XX
21[2-9]XXX
2[2-3]XXXX
24[0-4]XXX
245[0-1]XX
2452[0-3]X
24514[0-5]

這是我如何處理的第一個提示。 從最不重要的位置開始,利用對稱性,但處理我們碰到“金字塔頂端”的情況。 盡管這個示例很簡單,但是有很多極端情況會引起問題。 為了簡潔起見,我將不對每個細節進行詳細介紹,但我將對每個細節進行簡短說明:

如果兩個比較的數字之間有一個數字,例如46怎么辦?

在這種情況下,只需使用一位數字代替范圍。

如果兩個比較的數字之間沒有數字,例如45 ,您該怎么辦?

在這種情況下,請丟棄將要在其中處理數字之間數字的行,因為所有情況都將得到明確處理。

當范圍中的最小數字為8時,您會怎么做?

在這種情況下,當我們在數字上加1以得到范圍的下限時,我們得到9,這意味着我們可以簡單地用9代替范圍[9-9]

當范圍內的最小數字為9時,您會怎么做?

在這種情況下,我們根本不用理會這個數字,因為在處理下一個數字時,應該使用X來覆蓋它。

我確定我遺漏了我在代碼中處理過的一些極端情況,而我根本沒想到將它們放在此列表中。 如果您只想發表評論,我願意澄清代碼的任何部分。

下面是我在Go中的刺探。 可能會更干燥,但這是我擺弄一點之后想到的。 我對Go還是很陌生,因此請在評論中告知我任何精神上的犯規之處,我會予以糾正。

我不能保證這可以處理所有情況,但是可以處理我拋出的所有情況。 由您決定將其轉換為包含2個字符串的腳本;)

編輯:我只是通過問題中的示例(出於某種原因,我從未運行過)意識到這並不總是將所提供的范圍壓縮到最小數量的輸出中,但是它應該始終給出涵蓋所有情況的模式。 盡管存在這個缺點,我認為這是朝着正確方向邁出的良好一步,讓您可以繼續努力。 如果我有時間將其壓縮為先前范圍為1-9而特殊情況為0情況,我將更新答案。 最好的方法可能是在第一代人“手動”壓縮這些情況之后。

package main

import (
    "strconv"
    "fmt"
)


func getStringFromMinAndMax(min int, max int) (string, bool){
    minstr := strconv.Itoa(min)
    maxstr := strconv.Itoa(max)
    if max == min {
        return minstr, false
    }
    if max < min{
        return minstr, false
    }
    return "["+minstr+"-"+maxstr+"]", true
}
func main(){
    str1 := "211234"
    str2 := "245245"

    diffLength := 0
    for i := 0; i < len(str1); i++{
        diffLength = i+1
        number1, _ := strconv.Atoi(str1[:len(str1)-i-1])
        number2, _ := strconv.Atoi(str2[:len(str2)-i-1])
        if number1 == number2 {
            break
        }

    }

    elems := (diffLength * 2)-1
    output := make([]*[]string, elems+1)
    for i := 0; i < elems; i++ {
        newSlice := make([]string, diffLength)
        output[i] = &newSlice
    }

    for digit := 0; digit < diffLength; digit++ {
        for j := 0; j < diffLength; j++ {
            if j == digit {
                if output[j] != nil {
                    min, _ := strconv.Atoi(string(str1[len(str1)-(digit+1)]))
                    max := 9
                    if digit == diffLength-1 {
                        max, _ = strconv.Atoi(string(str2[len(str1)-(digit+1)]))
                        max = max - 1
                    }
                    if digit != 0{
                        min = min+1
                    }

                    if min < 10 {
                        maxchar := strconv.Itoa(max)[0]
                        minchar := strconv.Itoa(min)[0]
                        newVal, safe := getStringFromMinAndMax(min, max)
                        if digit == diffLength-1 && !safe && (str1[len(str1)-(digit+1)] == maxchar || str2[len(str2)-(digit+1)] == minchar) {
                            output[j] = nil
                        } else {
                            (*output[j])[diffLength-digit-1] = newVal
                        }
                    } else {
                        output[j] = nil
                    }
                }
                if j != diffLength-1 && output[elems-1-j] != nil {
                    min := 0
                    max, _ := strconv.Atoi(string(str2[len(str1)-(digit+1)]))
                    if digit != 0{
                        max = max-1
                    }
                    if max >= 0{
                        newVal, _ := getStringFromMinAndMax(min, max)
                        (*output[elems-1-j])[diffLength-digit-1] = newVal
                    } else {
                        output[elems-1-j] = nil
                    }
                }
            } else {
                if j > digit {
                    if output[j] != nil {
                        (*output[j])[diffLength-digit-1] = "X"
                    }
                    if j != diffLength-1 && output[elems-1-j] != nil {
                        (*output[elems-1-j])[diffLength-digit-1] = "X"
                    }
                } else {
                    if output[j] != nil {
                        (*output[j])[diffLength-digit-1] = string(str1[len(str1)-digit-1])
                    }
                    if j != diffLength-1 && output[elems-1-j] != nil {
                        (*output[elems-1-j])[diffLength-digit-1] = string(str2[len(str2)-digit-1])
                    }
                }
            }
        }
    }


    for _, list := range output {
        if list != nil{
            if len(str1) != diffLength{
                fmt.Printf(str1[:len(str1)-diffLength])
            }
            for _, element := range *list {
                fmt.Printf(element)
            }
            fmt.Printf("\n")
        }
    }
}

腳注:

  • diffLength是字符串末尾的字符數,它們不一樣,我想不到一個比腳本中更好的方法來獲取這個數字...
  • 我將輸出設置為nil就是說:“將對此進行明確處理,因此將其丟棄”
  • j是我要為其設置輸出的變量...但這也反映到底部,因此我想不出一個簡潔的名稱來命名它,因此我將其留給了j。
  • digit跟蹤我們正在修改的右側數字

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM