簡體   English   中英

如何將一個大數字作為字符串遞增,就像它是整數一樣?

[英]How to increment a large number as a string as if it were an integer?

我一直在想辦法做到這一點,我不能只是將字符串轉換為int。 成為一個整數太長了,這就是我需要這樣做的原因。 我可以將其設置為一位數字,但是一旦我想添加10或20,我就不確定如何更改代碼以允許這樣做。 如果增加循環,它將增加字符串的長度,並且不會將其視為實際數字。 之所以包含兩種語言,是因為我將在答案中接受C#或F#代碼。

open System

type String with
    member this.Last() =
        this.[this.Length - 1]

let mutable s = "1234567890" // the numbers I will use are a lot bigger than this.

for i in 0 .. 9 do // 9 is max before it increases the length of the string.
    printfn "%s" s

    let last = (s.Last().ToString() |> int) + 1

    s <- s.[0 .. s.Length - 2] + last.ToString()

Console.Read() |> ignore

我懷疑在任何情況下使用字符串表示數字是否是一個好主意-您可以使用BigInteger表示並處理大量數字,並且它支持所有數字運算,而不僅僅是增加一個。

但是,這是一個有趣的問題,因此這是一個可能的F#解決方案:

let incString (s:string) = 
  let rec loop acc carry i (s:string) =  
    match i, carry with 
    | -1, true -> System.String(Array.ofList ('1'::acc))
    | -1, false -> System.String(Array.ofList acc)
    | _ ->
      match s.[i], carry with 
      | '9', true -> loop ('0'::acc) true (i-1) s 
      | c, false -> loop (c::acc) false (i-1) s
      | c, true -> loop (char ((int c) + 1)::acc) false (i-1) s
  loop [] true (s.Length-1) s

incString "9899"

內部loop函數采用以下參數:

  • acc是一個累加器,用於收集新數字的數字(從結尾開始)
  • carry是一個布爾標志,是true ,如果我們要添加1到下一個數字(這是最初true ,然后它也是true ,只要數字是9 -因為9將成為0 ,我們則需要添加到字符串中的下一位)。

  • i是當前索引,從最后一個索引開始

  • s是代表原始數字的輸入字符串。

您將其反轉為字符列表,嘗試遞增最低位數,如果不起作用(它為9),則將最低位數設置為“ 0”並遞歸尾部

let inc: string -> string =
    let rec incRev: List<char> -> List<char> =             
        function
        | [] -> [ '1' ]
        | '9' :: cs -> '0' :: incRev cs
        | c :: cs -> char (int c + 1) :: cs
    fun s -> 
        s.ToCharArray() 
        |> Array.toList 
        |> List.rev
        |> incRev
        |> List.rev
        |> Array.ofList
        |> System.String

另一個可能稍微更有效的答案(我更喜歡上一個),但沒有所有反向操作。 您可以從字符列表的后面折疊來組合答案,並將進位數字傳遞到末尾。

let inc2: string -> string =
    let incDigit : (char * (List<char> * char)) -> (List<char> * char) =
        function 
        | (c,(a,'0'))   -> (c :: a,'0')
        | ('9',(a,'1')) -> ('0' :: a,'1')
        | (c,(a,'1'))   -> ((char (int c + 1)) :: a,'0')            
    fun s -> 
        let result = 
            (s.ToCharArray() 
            |> Array.toList 
            |> List.foldBack (fun c state -> incDigit (c,state))) ([],'1')
        result
        |> fst
        |> if (snd result = '1') then (fun cs -> '1' :: cs) else id
        |> Array.ofList
        |> System.String

暫無
暫無

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

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