大數相加算法實現

所謂的大數相加就是,數字的長度超出了計算機int64的存儲範圍,須要使用字符串存儲進行相加python

相加的邏輯,相似與咱們小學算加法,列等式進行相加,若是大於等於10則須要進位算法

下面將用不一樣語言來實現app

Python實現(支持帶小數點大數)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import random
import time

# 大數相加, 超出int64存儲範圍

def random_number():
  """
  隨機生成一個大數
  :return:
  """
  length = random.randint(99, 9999)
  s = ''
  for i in range(length):
    s += str(random.randint(0, 9))
  return s


def strToList(s):
  """
  字符串轉換爲列表
  :param s:
  :return:
  """
  l = []
  for i in range(len(s)):
    l.append(s[i])
  return l


def floadBigAdd(a, b, c, d):
  """
  計算帶小數點的大數
  :param a:
  :param b:
  :return:
  """
  max_x = max(len(c), len(d))  # 獲取小數點後最長的長度
  x = bigAdd(c, d)  # 計算小數點後相加的結果
  if len(x) > max_x:  # 若是小數點計算後長度大於原先的長度,則進行進位1,小數點計算去除第一位
    # 小數點前的數進行加1
    a_l = strToList(a)
    a_l[0] = str(int(a_l[0]) + 1)
    a = ''.join(a_l)
    # 小數點後的數去除第一位
    x_l = strToList(x)
    x_l.pop(0)
    x = ''.join(x_l)
  s = bigAdd(a, b)
  return s + '.' + x


def bigAdd(a, b):
  """
  大數相加
  :param a:
  :param b:
  :return:
  """
  # 反轉字符串以後轉換爲列表
  a = strToList(a[::-1])
  b = strToList(b[::-1])
  c = []  # 定義存儲結果的列表

  max_str = [0]  # 定義不一樣位數存儲列表,默認有一個數,若是位數相同且最後移爲計算進1爲,取值時會報錯
  # 獲取最短的數字長度
  if len(a) > len(b):
    length = len(b)
    max_str = a[length:]  # 取出最長字符串超出最短的部分
  elif len(a) < len(b):
    length = len(a)
    max_str = b[length:]
  else:
    length = len(a)

  t = 0  # 定義進位值
  for i in range(length):  # 循環計算值
    t1 = int(a[i]) + int(b[i])
    if t1 >= 10:
      t1 = t1 - 10
      c.append(str(t1 + int(t)))
      t = 1  # 大於10下一次計算進位1
    else:
      c.append(str(t1 + int(t)))
      t = 0  # 小於10下一次計算進位0
  if t == 1:  # 若是最後一次進位爲1,將在超出部分加1
    max_str[0] = str(int(max_str[0]) + t)
  if max_str[-1] == 0:
    max_str = []
  c.extend(max_str)  # 計算合併列表
  sum = ''.join(c)  # 拼接字符串
  return sum[::-1]  # 反轉字符串即爲最後的計算結果


def main(a, b):
  """
  算法開始
  :param a:
  :param b:
  :return:
  """
  start_time = time.time()

  if '.' in a or '.' in b:
    a1, a2 = a.split('.')[0], a.split('.')[1] if len(a.split('.')) > 1 else []
    b1, b2 = b.split('.')[0], b.split('.')[1] if len(b.split('.')) > 1 else []
    c = floadBigAdd(a1, b1, a2, b2)
  else:
    c = bigAdd(a, b)
  print("Use Time: ", time.time() - start_time)
  return c


if __name__ == '__main__':
  ty = input("select Type(r/i): ")  # 選擇是隨機生成大數,仍是手動輸入數字
  a, b = '', ''
  if ty == 'r':
    a, b = random_number(), random_number()
  elif ty == 'i':
    a = str(input('A= '))
    b = str(input('B= '))
  else:
    exit("Input Error")
  print("A(%s):" % (len(a)), a)
  print("B(%s):" % (len(b)), b)
  c = main(a, b)
  print(c)

GO語言實現

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

func bigAdd(str1, str2 string) (result string) {
    if len(str1) == 0 && len(str2) == 0 {
        return "0"
    }

    index1 := len(str1) - 1
    index2 := len(str2) - 1
    var left int

    for index1 >= 0 && index2 >= 0 {
        c1 := str1[index1] - '0'
        c2 := str2[index2] - '0'

        sum := int(c1) + int(c2) + left
        if sum >= 10 {
            left = 1
        } else {
            left = 0
        }
        c3 := (sum % 10) + '0'
        result = fmt.Sprintf("%c%s", c3, result)
        index1--
        index2--
    }

    for index1 >= 0 {
        c1 := str1[index1] - '0'

        sum := int(c1) + left
        if sum >= 10 {
            left = 1
        } else {
            left = 0
        }
        c3 := (sum % 10) + '0'
        result = fmt.Sprintf("%c%s", c3, result)
        index1--
    }

    for index2 >= 0 {
        c2 := str2[index2] - '0'

        sum := int(c2) + left
        if sum >= 10 {
            left = 1
        } else {
            left = 0
        }
        c3 := (sum % 10) + '0'
        result = fmt.Sprintf("%c%s", c3, result)
        index2--
    }

    if left == 1 {
        result = fmt.Sprintf("1%s", result)
    }
    return
}

func main() {
    r := bufio.NewReader(os.Stdin)
    s, _, error := r.ReadLine()
    if error != nil {
        fmt.Println("Input info has error:", error)
        return
    }
    strSlice := strings.Split(string(s), "+")
    if len(strSlice) <= 1 {
        fmt.Println("Input info has error")
        return
    }
    strNumber1 := strings.TrimSpace(strSlice[0])
    strNumber2 := strings.TrimSpace(strSlice[1])

    result := bigAdd(strNumber1, strNumber2)
    fmt.Println(result)
}
相關文章
相關標籤/搜索