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

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

[[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サベイニングはすでに存在していた

ブログ    
ブログ    

推薦する

インテリジェントな仮想アシスタントが2022年に生産性を2倍にする方法

翻訳者 | 張野貴校正 | 孫淑娟 良策インテリジェント仮想アシスタント市場の洞察インテリジェント ...

Googleの研究ディレクターはスタンフォード大学で教鞭をとり、「人工知能:現代的アプローチ」の著者でもある。

スタンフォード大学は10月11日、Googleリサーチディレクターのピーター・ノーヴィグ氏がスタンフ...

小売業における人工知能:生き残りは賢くなることにかかっている

機械学習は、ビジネスを急速に成長させたい小売業者にとって急速に必要不可欠なものになりつつありますが、...

...

ディープラーニングに関する面接で絶対に聞きたい12の質問

導入これら 12 の質問は、現在の面接で最も人気のある質問です。これらは非常に基本的な質問ですが、面...

ソフトウェアプログラマー試験: 関数の最大値を見つけるための標準的な遺伝的アルゴリズム

Dim N2 (30) Longは2の累乗されたデータを格納するために使用されるDim Script...

3月にGithubで最も人気のあるデータサイエンスと機械学習のプロジェクト

Analytics Vidhya は最近、3 月の GitHub で上位 5 つのデータ サイエンス...

アリババクラウド南京雲奇カンファレンス:スマート製造モデルの共有と最先端技術の発表

[51CTO.comより引用] 本日、アリババクラウドカンファレンス南京サミットが正式に開催され、ま...

ChatGPT パラメータが 200 億しかないとは思いませんでした。

ChatGPT の核心的な秘密が Microsoft によってこのように暴露されるとは誰も予想して...

人工知能、自動化、そして仕事の未来: 答えが必要な 10 の質問!

[[264418]]職場で機械が人間の労働に取って代わるようになるにつれ、私たち全員が機械から利益...

ディープラーニングを使用した DGA (ドメイン生成アルゴリズム) の検出

[[196872]] DGA (ドメイン生成アルゴリズム) は、ドメイン名のブラックリスト検出を回避...

世界人工知能会議が開幕。ジャック・マー、ロビン・リー、イーロン・マスクらは何を語ったのか?

昨日、第3回世界人工知能大会が予定通り開催され、ジャック・マー氏、ロビン・リー氏、任宇新氏など国内の...

TensorFlow を使用してシンプルなロジスティック回帰モデルをゼロから構築する

TensorFlow は Python ベースの機械学習フレームワークです。 Coursera でロ...

今日の企業で人気の AI ユースケース 12 選

世界中の企業が、プロセスの合理化、コストの最適化、人的エラーの防止、顧客の支援、IT システムの管理...

...