[文字列処理アルゴリズム] 最長共通部分文字列を取得するためのアルゴリズム設計とCコード実装

[文字列処理アルゴリズム] 最長共通部分文字列を取得するためのアルゴリズム設計とCコード実装

1. 要件の説明

2 つの文字列を入力し、2 つの文字列の最長共通部分文字列を取得するプログラムを作成します。

たとえば、入力文字列が「abcdef」と「fecdba」の場合、これら 2 つの文字列の最長共通部分文字列は「cd」です。

2. アルゴリズム設計

まず、2 つの文字列で最初の等しい文字を見つけ、次に後方に移動して、対応する位置の文字が等しいかどうかを比較します。

つまり、文字列 1 が「1234abcd」で文字列 2 が「abd」の場合、まず文字列 1 の 5 番目の文字「a」が文字列 2 の最初の文字「a」と等しいことがわかり、次に文字列 1 の 6 番目の文字「b」が文字列 2 の 2 番目の文字「b」と等しく、次に文字列 1 の 7 番目の文字「c」が文字列 2 の 3 番目の文字「d」と等しくないことが判明し、この時点で比較が終了します。つまり、文字列 1 と文字列 2 の最長共通部分文字列は「ab」です。

3. 特別なプロセスに関する考慮事項

プログラムを作成する過程では、次のような入力文字列の長さと形式を考慮する必要があります。

1. 2 つの入力文字列の 1 つに中国語の文字が含まれている場合、プログラムは後続の処理を実行せずに直接戻ります。

2. 2 つの入力文字列の 1 つにスペースが含まれている場合、プログラムは後続の操作のためにスペースの前の文字列を取得します。

4. プログラムコード

  1. /******************************************************************************************
  2. * 著作権 (C) 2016、Zhou Zhaoxiong。
  3. *
  4. * ファイル名: GetLCS.c
  5. * ファイルID: なし
  6. * 概要: 2つの文字列の最長共通部分文字列を見つける
  7. * その他の注意: たとえば、「abcdef」と「bcf」の最長共通部分文字列は「bc」です。
  8. * 現在のバージョン: V1.0
  9. * 著者: 周昭雄
  10. * 完成日: 20160322
  11. *
  12. ******************************************************************************/
  13. #include < stdio.h >  
  14. #include <文字列.h >  
  15. #include < stdlib.h >  
  16.  
  17.  
  18. // データ型を再定義する
  19. typedef signed char INT8;
  20. 型定義 int INT32;
  21. typedef 符号なし int UINT32;
  22.  
  23. // 関数宣言
  24. void GetLCSOfTwoStr(INT8 *pszInputStr1、INT8 *pszInputStr2);
  25.  
  26.  
  27. /******************************************************************************************
  28. * 機能説明: 主な機能
  29. * 入力パラメータ: なし
  30. * 出力パラメータ: なし
  31. * 戻り値: 0 - 実行成功 その他 - 実行失敗
  32. * その他の指示: なし
  33. * 変更日 バージョン番号 修正者 変更内容
  34. * ---------------------------------------------------------------------
  35. * 20160322 V1.0 作成者: Zhou Zhaoxiong
  36. ******************************************************************************/
  37. INT32 メイン()
  38. {
  39. INT8 szInputStr1[100] = {0};
  40. INT8 szInputStr2[100] = {0};
  41. UINT32 iPosFlag = 0 ;
  42.      
  43. printf("文字列1を入力してください:\n");
  44. scanf("%s", szInputStr1);
  45. printf(" InputStr1 =%s\n", szInputStr1);
  46.  
  47. printf("文字列2を入力してください:\n");
  48. scanf("%s", szInputStr2);
  49. printf(" InputStr2 =%s\n", szInputStr2);
  50.  
  51. // まず中国語の文字があるかどうかを確認します
  52. ( iPosFlag = 0 ; iPosFlag <   strlen (szInputStr1); iPosFlag++)
  53. {
  54. if (szInputStr1[iPosFlag] <   0 ) // 0未満は中国語の文字が含まれていることを意味します
  55. {
  56. printf("%s には中国語の文字が含まれています。確認してください!\n", szInputStr1);
  57. -1 を返します。
  58. }
  59. }
  60.  
  61. ( iPosFlag = 0 ; iPosFlag <   strlen (szInputStr2); iPosFlag++)
  62. {
  63. if (szInputStr2[iPosFlag] <   0 ) // 0未満は中国語の文字が含まれていることを意味します
  64. {
  65. printf("%s には中国語の文字が含まれています。確認してください!\n", szInputStr2);
  66. -1 を返します。
  67. }
  68. }
  69.  
  70. // 関数を再度呼び出して、2つの文字列の最長共通部分文字列を取得します
  71. GetLCSOfTwoStr(szInputStr1、szInputStr2);
  72.  
  73. 0を返します。
  74. }
  75.  
  76.  
  77. /******************************************************************************************
  78. * 関数の説明: 2つの文字列の最長共通部分文字列を取得します
  79. * 入力パラメータ: pszInputStr1-入力文字列1
  80. pszInputStr2 - 入力文字列2
  81. * 出力パラメータ: なし
  82. * 戻り値: なし
  83. * その他の指示: なし
  84. * 変更日 バージョン番号 修正者 変更内容
  85. * ---------------------------------------------------------------------
  86. * 20160322 V1.0 作成者: Zhou Zhaoxiong
  87. ******************************************************************************/
  88. void GetLCSOfTwoStr(INT8 *pszInputStr1、INT8 *pszInputStr2)
  89. {
  90. UINT32 iInnerLoopF​​lag = 0 ;
  91. UINT32 iOutterLoopF​​lag = 0 ;
  92. UINT32 iPosFlag = 0 ;
  93. UINT32 iLCSLen = 0 ;
  94. INT32 i開始位置= -1;
  95. INT8 szLCS[100] = {0};
  96.      
  97. pszInputStr1 == NULL || pszInputStr2 == NULLの場合
  98. {
  99. 戻る;
  100. }
  101.  
  102. ( iOutterLoopF ​​lag = 0 ; iOutterLoopF​​lag <   strlen (pszInputStr1); iOutterLoopF​​lag++)
  103. {
  104. ( iInnerLoopF​​lag = 0 ; iInnerLoopF​​lag <   strlen (pszInputStr2); iInnerLoopF​​lag++)
  105. {
  106. pszInputStr1[iOutterLoopF​​lag] == pszInputStr2[iInnerLoopF​​lag]の場合
  107. {
  108. ( iPosFlag = 1 ; pszInputStr1[iOutterLoopF​​lag+iPosFlag] != '\0'; iPosFlag ++)の場合
  109. {
  110. if (pszInputStr1[iOutterLoopF​​lag+iPosFlag] != pszInputStr2[iInnerLoopF​​lag+iPosFlag]) // 等しくない文字が見つかった場合は比較を終了します
  111. {
  112. 壊す;
  113. }
  114. }
  115.  
  116. if (iLCSLen <   iPosフラグ)
  117. {
  118. iLCSLen = iPosFlag ;
  119. iStartPos = iOutterLoopF​​lag ;
  120. }
  121. }
  122. }
  123. }
  124.    
  125. ( iStartPos == -1 の場合)
  126. {
  127. memset(szLCS, 0x00, sizeof(szLCS));
  128. }
  129. それ以外
  130. {
  131. memcpy(szLCS, &pszInputStr1[iStartPos], iLCSLen);
  132. }
  133.  
  134. (iLCSLen > 0)の場合
  135. {
  136. printf("%s と %s の最長共通部分文字列は: %s、その長さは: %d\n", pszInputStr1, pszInputStr2, szLCS, iLCSLen);
  137. }
  138. それ以外
  139. {
  140. printf("%s と %s には共通の部分文字列がありません!\n", pszInputStr1, pszInputStr2);
  141. }
  142. }

5. プログラムのテスト

作成したプログラム「GetLCS.c」を Linux マシンにアップロードし、「gcc -g -o GetLCS GetLCS.c」コマンドを使用してプログラムをコンパイルし、「GetLCS」ファイルを生成します。以下はプログラムの詳細なテストです。

1. 入力文字列 1 が「abcdef」、文字列 2 が「hijkabm」の場合、プログラムは次のように実行されます。

  1. 文字列1を入力してください:
  2. ABCデフ
  3. 入力Str1 = abcdef  
  4. 文字列2を入力してください:
  5. ヒジカブム
  6. 入力Str2 = hijkabm  
  7. abcdefとhijkabmの最長共通部分文字列はabであり、その長さは2である。

2. 入力文字列 1 が「1234!@#」、文字列 2 が「5678!@#1」の場合、プログラムは次のように実行されます。

  1. 文字列1を入力してください:
  2. 1234!@#
  3. 入力Str1 = 1234 !@#
  4. 文字列2を入力してください:
  5. 5678!@#1
  6. 入力Str2 = 5678 !@#1
  7. 1234!@#と5678!@#1の最長共通部分文字列は:!@#で、その長さは: 3

3. 入力文字列 1 が「123你好」、文字列 2 が「123」の場合、プログラムは次のように実行されます。

  1. 文字列1を入力してください:
  2. 123 こんにちは
  3. InputStr1 = 123こんにちは
  4. 文字列2を入力してください:
  5. 123
  6. 入力Str2 = 123  
  7. 123Helloには中国語の文字がありますので、確認してください。

4. 入力文字列 1 が「123abc」、文字列 2 が「abd ef」の場合、プログラムは次のように実行されます。

  1. 文字列1を入力してください:
  2. 123abc
  3. 入力Str1 = 123abc  
  4. 文字列2を入力してください:
  5. アブドエフ
  6. 入力Str2 = abd  
  7. 123abcとabdの最長共通部分文字列はabであり、その長さは2である。

5. 入力文字列 1 が「abcdef」、文字列 2 が「123456」の場合、プログラムは次のように実行されます。

  1. 文字列1を入力してください:
  2. ABCデフ
  3. 入力Str1 = abcdef  
  4. 文字列2を入力してください:
  5. 123456
  6. 入力Str2 = 123456  
  7. abcdef と 123456 には共通の部分文字列がありません。

6. 需要拡大

この記事の要件と手順に基づいて、要件の次の拡張を検討できます。

1. 2 つの文字列に複数の最長共通部分文字列がある場合、それらを出力する必要があります。つまり、文字列 1 が「1234abcd」で文字列 2 が「abd12」の場合、プログラムによって入力される最長共通部分文字列は「12」と「ab」です。

2. 入力文字列に中国語の文字が出現できないという制限はありません。つまり、文字列 1 が「我们123」で文字列 2 が「我们」の場合、最長共通部分文字列は「我们」です。

[この記事は51CTOコラムニストの周兆雄氏によるオリジナル記事です。著者のWeChat公開アカウント:周の論理(logiczhou)]

この著者の他の記事を読むにはここをクリックしてください

<<:  特定の文字を削除するためのアルゴリズム設計とCコードの実装

>>:  同じプレフィックスとサフィックスを持つファイルを同じディレクトリに移動するためのアルゴリズム設計と C コードの実装

ブログ    
ブログ    

推薦する

どのような状況で Redis のメモリ オーバーフローが発生しますか?解決策は何ですか?

Redis のメモリ オーバーフローの問題は、通常、次のような状況によって発生します。データが多す...

データ センターはリモート ワークプレイスをどのようにサポートできるでしょうか?

COVID-19の時代となり、さまざまな業界や組織でリモートワークが始まっています。企業は、遠隔地...

中国 NeurIPS の著者の 54% が米国へ:ケンブリッジ AI パノラマ レポートが発表

NeurIPSに受理された論文のうち、著者の29%は中国の大学で学士号を取得していますが、そのうち...

次世代人工知能

[[390934]] AI と機械学習の最近の研究では、一般的な学習と、ますます大規模なトレーニング...

英国最高裁:特許の「発明者」は人工知能ではなく自然人でなければならない

ロイター通信は12月21日、現地時間20日に発表された英国最高裁判所の判決で、米国のコンピューター科...

...

人工知能チュートリアル(II):人工知能の歴史とマトリックスの再考

このシリーズの最初の記事では、人工知能、機械学習、ディープラーニング、データサイエンスなどの分野間の...

...

産業用ロボットはセンサーなしでも動作できますか?

現在、人口ボーナスの減少、人件費の上昇、人材構成の矛盾などの問題が、製造業の発展を阻む困難になりつつ...

ヘルスケアの革命: アジア太平洋地域におけるスマートホーム技術の台頭

アジア太平洋地域では、スマートホーム技術の登場により、ヘルスケア業界の大きな変革が起こっています。こ...

何?ニューラルネットワークは新しい知識も生み出せるのでしょうか?

作業を実行するための明示的なアルゴリズムを知らなくても、特定のタスク用にニューラル ネットワーク (...

人工知能の台頭によりプログラマーは消滅するのでしょうか?

ローコードおよびノー​​コード プラットフォームの爆発的な成長により、個人でも組織でも、従来はコード...

...

BBCはOpenAIによるデータスクレイピングをブロックしているが、ニュースでのAIの使用にはオープンである

英国最大の報道機関であるBBCは10月7日、ニュース、アーカイブ、「パーソナライズされた体験」の研究...