これを読めば、大きな整数の乗算と分割統治アルゴリズムを学ぶことができます。

これを読めば、大きな整数の乗算と分割統治アルゴリズムを学ぶことができます。

[[352004]]

データ暗号化処理には多くの複雑な暗号化アルゴリズムがあり、これらの暗号化アルゴリズムでは非常に大きな整数演算が多数使用されることがよくあります。しかし、プログラミング言語にはデータのサイズに一定の制限があり、データが大きすぎるとデータオーバーフローが発生し、大きな整数データの操作が実行できなくなります。この記事では、大きな整数に対するデータ操作を実装する方法を学びます。この記事のコードは C++ を使用して実装します。

一般的な乗算演算

掛け算の計算には比較的簡単でわかりやすい方法があります。小学校で習った縦割りの計算法を使って掛け算の計算をすることができます。

垂直乗算

上図の列計算方法を参考にコードを実装します。

  1. #include <iostream>
  2. #include <文字列>
  3. #include <stdlib.h>
  4. #include <ベクター>
  5. #include <cstring>
  6. #include <アルゴリズム>
  7.  
  8. std::string を乗算します (std::string a、std::string b)
  9. {
  10. std::string 結果 = "" ;
  11. int行 = b.size ( );
  12. サイズを整数にする
  13. int tmp[行][列];
  14. memset(tmp,0,sizeof( int )*row*col);
  15.      
  16. 逆順( a.begin (),a.end ( ));
  17. 逆順( b.begin (),b.end ( ));
  18.      
  19. ( int i = 0; i < b.size ( ) ); i++)の場合
  20. {
  21. ( int j = 0; j < a.size ( ) ); j++)の場合
  22. {
  23. std::string bit_a = std::string(1, a.at (j));
  24. std::string bit_b = std::string(1, b.at (i));
  25.              
  26. tmp[i][j] += std::stoi(bit_a) * std::stoi(bit_b);
  27.          
  28. tmp[i][j+1] = tmp[i][j] / 10;
  29. tmp[i][j] % = 10;
  30.  
  31. }
  32.  
  33. }
  34.  
  35. int N = a.size ( ) + b.size ( );
  36. 整数 合計[N];
  37. memset(合計, 0, sizeof( int )*N);
  38.      
  39. ( int n = 0; n < N; n++)の場合
  40. {
  41. 整数i = 0;
  42. 整数j = n;
  43.          
  44. i <= n && j >= 0 の場合
  45. {
  46. if(i < 行 && j < 列)
  47. {
  48. 合計[n] += tmp[i][j];
  49. }
  50.              
  51. 私は++;
  52. j --;  
  53. }
  54.  
  55. (n+1 < N)の場合
  56. {
  57. 合計[n+1] =合計[n] / 10;
  58. 合計[n] %= 10;
  59. }
  60.  
  61. }
  62.  
  63. ブールゼロ開始フラグ = true ;
  64. ( int i = N-1; i >= 0; i --)の場合 
  65. {
  66. if(合計[i] = = 0 && ゼロ開始フラグ)
  67. {
  68. 続く;
  69. }
  70.          
  71. ゼロ開始フラグ = false ;
  72. 結果を追加します(std::to_string(合計[i]));
  73. }
  74.      
  75. 結果を返します
  76. }
  77.  
  78.  
  79. intメイン()
  80. {
  81. std::string a = "3456" ;
  82. std::string b = "1234" ;
  83.  
  84. std::string 結果 = multiply(a, b);
  85. std::cout << a << " * " << b << " = " << 結果 <<std::endl;
  86.      
  87. 0を返します
  88. }

便宜上、最初に各乗数を反転し、最後に結果を反転します。計算処理では、乗算結果を格納する配列を同じ列にシフトして加算するのではなく、斜めに加算することで、スペースと計算ステップを削減できます。上記のコードを実行した結果は以下のようになります。

運用結果

文字列の長さには特別な制限がないため、上記のアルゴリズムは大きな整数演算に適用できます。

分割統治アルゴリズム

上記の垂直列方式は大きな整数の乗算の問題を非常にうまく解決できますが、より効率的な方法である分割統治アルゴリズムを選択することもできます。クイックソートやバイナリサーチなど、多くの分野に応用できる非常に重要なアルゴリズムです。アルゴリズムの名前から、大きな問題を小さな問題に分割し、最初に小さな問題を解決してから最後にこの問題を解決することがわかります。そのため、分割統治法と呼ばれています。ここで、この方法を使用して、大きな整数をプログラミング言語を使用して直接計算できる小さな整数に分割し、最終的に大きな整数の値を取得できます。

2 つの大きな整数があるとします。これを a (サイズは n ビット) と b (サイズは m ビット) と設定します。ここではバイナリ検索法を使用してデータを分割します。これら 2 つの整数は次のように分解できます。

しかし、

作る、

上記の式によれば、a*b を 4 つの小さな整数の乗算、つまり 4 つの式 z3、z2、z1、z0 に分解できます。分解された乗算値がまだ大きい場合は、コンピュータープログラミング言語が直接計算できるようになるまで、同じ方法で分解を続け、より小さな乗算値に分解することができます。

例えば、上記の 3456 と 1234 を掛け合わせる場合、下の図を参考にして、バイナリ検索で整数を段階的に分割します。計算のために、2 つの整数を 1 桁の整数に分割します。

3456 と 1234 の分割手順図

次に、分割統治アルゴリズムのコード実装を見てみましょう。ここでは再帰的な方法を使用します。

  1. #include <iostream>
  2. #include <文字列>
  3. #include <stdlib.h>
  4. #include <ベクター>
  5. #include <cstring>
  6. #include <アルゴリズム>
  7. #include <cmath>
  8.  
  9. std::stringを追加します(std::string a、std::string b)
  10. {
  11. int N = std:: max ( a.size (), b.size ( ));
  12. 整数 合計[N];
  13. memset(合計, 0, sizeof( int )*N);
  14.      
  15. 逆順( a.begin (),a.end ( ));
  16. 逆順( b.begin (),b.end ( ));
  17.  
  18. ( int i = 0; i< N; i++)の場合
  19. {
  20. 整数ビットa = 0;
  21. ビットb = 0;
  22. i < a.size () の場合、 bit_a = std::stoi(std::string(1, a.at ( i)));
  23. i < b.size () の場合、bit_b = std::stoi(std::string(1, b.at ( i)));
  24.  
  25. 合計[i] += (bit_a + bit_b);
  26.  
  27. i < N-1 &&合計[i]>9 の場合
  28. {
  29. 合計[i+1] =合計[i] / 10;
  30. 合計[i] %=10;
  31. }
  32. }
  33.  
  34. std::string 結果 = "" ;
  35. ブールゼロ開始フラグ = true ;
  36. ( int i = N-1; i >= 0; i --)の場合 
  37. {
  38. if(合計[i] = = 0 && ゼロ開始フラグ)
  39. {
  40. 続く;
  41. }
  42.          
  43. ゼロ開始フラグ = false ;
  44. 結果を追加します(std::to_string(合計[i]));
  45. }
  46.  
  47.  
  48. 結果を返します
  49. }
  50.  
  51. std::string の分割と征服 (std::string a、std::string b)
  52. {
  53. a.size () < 2 && b.size ( ) < 2の場合
  54. {
  55. std::to_string(std::stoi(a) * std::stoi(b))を返します
  56. }
  57.      
  58. int n = a.size ( );
  59. b.size ( ) は、文字列の先頭に0 を付加します。
  60.      
  61. 整数半分N = n/2;
  62. 整数半分M = m/2;
  63.  
  64. std::string a0 = "0" ;
  65. std::string a1 = "0" ;
  66. if( a.size () > halfN && halfN > 0)
  67. {
  68. a1 = a.substr(0, 半分N);
  69. a0 = a.substr(halfN, a.size () - halfN);
  70. }
  71. それ以外 
  72. {
  73. a1 = "0" ;
  74. 0 = 0;
  75. }
  76.      
  77. std::string b0 = "0" ;
  78. std::string b1 = "0" ;
  79. b.size () > halfM && halfM > 0の場合
  80. {
  81. b1 = b.substr(0, halfM);
  82. b0 = b.substr(halfM, b.size () - halfM);
  83.  
  84. }
  85. それ以外 
  86. {
  87. b1 = "0" ;
  88. 0 = 0;
  89. }
  90.  
  91. std::string a1b1 = 分割して征服します(a1、b1);
  92. std::string a0b0 = 分割して征服する(a0, b0);
  93. std::string a1b0 = 分割して征服する(a1、b0);
  94. std::string a0b1 = 分割して征服します(a0、b1);
  95.      
  96. a1b1.append((n - 半分N) + (m - 半分M), '0' );
  97. a1b0.append(n - 半分のN、 '0' );
  98. a0b1.append(m - halfM, '0' );
  99.  
  100. std::string 結果 = "" ;
  101. 結果 = (a1b1, a1b0)を追加します
  102. 結果 =追加(結果、a0b1);
  103. 結果 =追加(結果、a0b0);
  104.  
  105. 結果を返します
  106. }
  107.  
  108. intメイン()
  109. {
  110. std::string a = "3456" ;
  111. std::string b = "1234" ;
  112.  
  113. std::cout << a << " * " << b << " = " <<divideAndConquer(a, b) << std::endl;
  114.  
  115. 0を返します
  116. }

プログラムの実行結果は次のとおりです。

分割統治アルゴリズムの演算結果

この記事はWeChat公式アカウント「Will's Canteen」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、Will’s Dashitang パブリックアカウントにご連絡ください。

<<:  機械学習が金融業界にもたらす破壊的変化

>>:  韓国初のAI女性キャスターが誕生。本物と間違えられ議論を巻き起こす。AIサベイニングはすでに存在していた

推薦する

...

百度地図のデータ収集リンクの80%はAIベースになっており、旅行業界はインテリジェントにアップグレードされている

人工知能時代の地図データ制作はどのような変化を遂げるのでしょうか?7月3日、「Baidu Creat...

AI イニシアチブを成功させるために必要な 10 のこと

市場で競争上の優位性を獲得する過程で、多くの企業が新興技術の導入に熱心です。しかし、導入を急ぐあまり...

...

「安佳」の人工知能版? 「AI仲介人」が近々登場?

この記事は公開アカウント「Reading Core Technique」(ID: AI_Discov...

人工知能は人間の知能ではない。まずは人工的なもの、そして知的なもの

人工知能に関しては、インターネット企業はすべてが「魔法のようだ」とよく言います。しかし、そうではあり...

AIの4つのタイプについてお話しましょう

人工知能が流行するにつれ、人々はそれがどのように機能し、何ができるのかについて多くの疑問を抱いていま...

RPAと医療におけるインテリジェントオートメーションの台頭

デジタル変革はヘルスケアにおける大きなトレンドと考えられており、インテリジェントな自動化もその一部と...

...

自動運転には未来があるのでしょうか?

自動運転の定義この記事では、飛行機や船ではなく、自動車の自動運転について説明します。英語ではこれを自...

ニューラル放射線フィールドは「神経」を取り除き、3D効果の品質を低下させることなくトレーニング速度を100倍以上向上させます。

2020年、カリフォルニア大学バークレー校、Google、カリフォルニア大学サンディエゴ校の研究者...

チャットテクノロジーと IoT セキュリティの将来はどうなるのでしょうか?

OpenAIは2022年11月30日にChatGPTをリリースしました。大規模言語モデル GPT3...

GPT-3は創造性に欠けるにもかかわらず、わずか20分で合格できる大学論文を書いた。

GPT-3で書かれた論文は通過したのでしょうか?教育リソースウェブサイトEduRefがこれに関する...

中国チームがボストン・ダイナミクスに対抗する四足歩行ロボットを発表

本日、Yushu Technology は、中国で正式に一般に公開される初の四足歩行ロボットとなる四...