C ++
 Computer >> コンピューター >  >> プログラミング >> C ++

C++での文字列変換のインプレースアルゴリズム


特定の文字列について、偶数に配置されたすべての要素を文字列の最後に転送します。要素を転送するときは、すべての偶数位置と奇数位置の要素の相対的な順序を同じに保ちます。

たとえば、指定された文字列が「a1b2c3d4e5f6g7h8i9j1k2l3m4」の場合、その文字列を「abcdefghijklm1234567891234」にインプレースでO(n)時間計算量に変換します。

次の手順は次のとおりです

  • 3 ^ k + 1の形式のサイズの最も高いプレフィックスサブ文字列を切り取ります。このステップでは、3 ^ k + 1がn(文字列の長さ)以下になるように、最も高い非負の整数kを見つけます。 )

  • このサブ文字列に対して、インデックス1、3、9……から始まるサイクルリーダー反復アルゴリズム(以下で説明)を実装します。サイクルリーダー反復アルゴリズムは、このサブストリングのすべての項目を正しい位置に転送します。つまり、すべてのアルファベットがサブストリングの左半分に移動され、すべての数字がこのサブストリングの右半分に移動されます。 。

  • 残りのサブストリングを再帰的に処理して、ステップ番号を実装します。 1といいえ。 2.

  • 現在、処理されたサブ文字列を結合するだけで済みます。任意の端から開始し(たとえば左から)、2つのサブ文字列を選択し、次の手順を実行します-

    • 最初のサブストリングの後半を正反対または逆にします。

    • 2番目のサブストリングの前半を正反対または逆にします。

    • 最初のサブストリングの後半と2番目のサブストリングの前半を一緒に正反対または逆にします。

  • 手順番号を繰り返します。 4すべてのサブ文字列が結合されるまで、および結合されない限り。これは、最初のサブストリングが2番目のサブストリングと結合されるk-wayマージと同じです。結果は3番目などとマージされます。

上記のアルゴリズムに基づいたコードを以下に示します-

// C++ application of above approach
#include <bits/stdc++.h>
using namespace std;
// A utility function to swap characters void swap ( char* a1, char* b1 ) {
   char t = *a1; *a1 = *b1; *b1 = t;
}
// A utility function to reverse string str1[low1..high1]
void reverse ( char* str1, int low1, int high1 ) {
   while ( low < high ) {
      swap(&str1[low1], &str1[high1] ); ++low1; --high1;
   }
}
// Cycle leader algorithm to shift all even
// positioned elements at the end.
void cycleLeader ( char* str1, int shift1, int len1 ) {
   int j;
   char item1;
   for (int i = 1; i < len1; i *= 3 ) {
      j = i; item1 = str1[j + shift1];
      do{
         // odd index if ( j & 1 )
         j = len1 / 2 + j / 2;
         // even index or position else j /= 2;
         // keep the back-up of element at new index or position
         swap (&str1[j + shift1], &item1);
      }
   while ( j != i );
   }
}
// The main function to convert a string. This function
// mainly implements cycleLeader() to convert void moveNumberToSecondHalf( char* str1 ) {
   int k, lenFirst1; int lenRemaining1 = strlen( str1); int shift1 = 0;
   while ( lenRemaining1) {
      k = 0;
      // Step 1: Find the highest prefix
      // subarray of the form 3^k + 1
      while ( pow( 3, k ) + 1 <= lenRemaining1)
      k++; lenFirst1 = pow( 3, k - 1 ) + 1;
      lenRemaining1 -= lenFirst1;
      // Step 2: Implement cycle leader algorithm
      // for the highest subarray cycleLeader ( str1, shift1, lenFirst1 );
      // Step 4.1: Just opposite or reverse the second half of first subarray reverse ( str1,
         shift1/2, shift1 - 1 );
      // Step 4.2: Just opposite or reverse the first half of second sub-string. reverse ( str1,
         shift1, shift1 + lenFirst1 / 2 - 1 );
      // Step 4.3 Just opposite or reverse the second half of first sub-string and first half of
         second sub-string together reverse ( str1, shift1 / 2, shift1 + lenFirst1 / 2 - 1 );
      // Now increase the length of first subarray Shift1 += lenFirst1;
  }
}
// Driver program to verify or test above function int main() {
   char str1[] = "a1b2c3d4e5f6g7"; moveNumberToSecondHalf( str1 ); cout<<str1; return 0;
}

出力

abcdefg1234567

  1. C++での符号なし整数の除算アルゴリズムの復元

    除算アルゴリズムを使用して符号なし整数を除算する方法について説明します。一部の除算アルゴリズムは紙に適用され、その他はデジタル回路に実装されます。除算アルゴリズムには、低速除算アルゴリズムと高速除算アルゴリズムの2種類があります。低速除算アルゴリズムには、復元、非実行復元、SRT、および非復元アルゴリズムが含まれます。 このチュートリアルでは、0<除数<被除数を想定した復元アルゴリズムについて説明します。 解決策を見つけるためのアプローチ ここでは、レジスタQを使用して商を格納し、レジスタAを使用して剰余を格納し、Mを使用して除数を格納します。 Aの初期値は0に保たれ、その値が復元されます

  2. 最適なページ置換アルゴリズムのためのC++プログラム

    与えられたページ番号とページサイズ。タスクは、最適なページ置換アルゴリズムを使用してメモリブロックをページに割り当てるときのように、ヒットとミスの数を見つけることです。 最適なページ置換アルゴリズムとは何ですか? 最適なページ置換アルゴリズムは、ページ置換アルゴリズムです。ページ置換アルゴリズムは、どのメモリページを置換するかを決定するアルゴリズムです。最適なページ置換では、実際には実装できませんが、近い将来に参照されないページを置換しますが、これは最適であり、ミスが最小限であり、最適です。 例を使って図式的に説明して理解しましょう。 ここで、1、2、3を割り当てた後、メモリが