繁体   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