【文字列処理アルゴリズム】回文判定のアルゴリズム設計とCコード実装

【文字列処理アルゴリズム】回文判定のアルゴリズム設計とCコード実装

1. 要件の説明

文字列を入力し、その文字列が回文であるかどうかを判断するプログラムを作成します。

便宜上、入力文字列は中国語文字列と非中国語文字列の 2 種類に分かれていると仮定します。中国語文字列には中国語の文字のみが含まれ、中国語以外の文字列には中国語の文字が含まれません。

回文とは、前から読んでも後ろから読んでも同じ文字列のことです。以下にいくつかの例を挙げて説明します。

1. 「level」は非中国語文字の回文です。正読も逆読も「level」だからです。

2. 「Good」は非中国語の文字の回文ではありません。

3. 「我愛我」は漢字の回文です。正読も逆読も「我愛我」となるからです。

4. 「愛しています」は漢字の回文ではありません。

2. アルゴリズム設計

非中国語文字の回文文字列の判定は比較的簡単です。文字列の中央を起点として、前後の対応する文字が等しいかどうかを比較するだけです。ただし、中国語文字の回文文字列の判定は、中国語文字が 2 バイトを占めるため、少し複雑です。非中国語文字の回文文字列の判定方法は使用できません。代わりに、最初に各中国語文字を個別に取得し、次に前後の 2 つの文字が等しいかどうかを比較する必要があります。

プログラムの全体的な流れを図 1 に示します。

図1 プログラムの全体的なプロセス

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

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

1. 入力文字列に 1 文字しか含まれていない場合、回文文字列には少なくとも 2 文字以上が含まれているため、プログラムは後続の処理を実行せずに直接戻ります。

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

4. プログラムコード

  1. /******************************************************************************************
  2. * 著作権 (C) 2016、Zhou Zhaoxiong。
  3. *
  4. * ファイル名: PalindromicString.c
  5. * ファイルID: なし
  6. * 内容概要: 回文判定
  7. * その他の注意: madam、php、2992、1234321 などの文字列は回文です。
  8. * 現在のバージョン: V1.0
  9. * 著者: 周昭雄
  10. * 完成日: 20160222
  11. *
  12. ******************************************************************************/
  13. #include < stdio.h >  
  14.  
  15.  
  16. // データ型を再定義する
  17. typedef signed char INT8;
  18. 型定義 int INT32;
  19. typedef 符号なし int UINT32;
  20.  
  21. // グローバル変数宣言。中国語の文字を格納するために使用します。*** 100 文字の中国語をサポートします
  22. INT8 gszStrCharArray[101][5] = {0};
  23. UINT32 giCharNum = 0 ;
  24.  
  25.  
  26. // 関数宣言
  27. void JudgePalindromicString(INT8 *pszInputStr、UINT32 iInputStrLen、UINT32 iStrType);
  28. void GetChineseChars(INT8 *pszInputStr);
  29. INT32 判定Strフォーマット(INT8 *pszInputStr、UINT32 iStrType);
  30.  
  31.  
  32. /******************************************************************************************
  33. * 機能説明: 主な機能
  34. * 入力パラメータ: なし
  35. * 出力パラメータ: なし
  36. * 戻り値: 0 - 実行成功 その他 - 実行失敗
  37. * その他の指示: なし
  38. * 変更日 バージョン番号 修正者 変更内容
  39. * ---------------------------------------------------------------------
  40. * 20160222 V1.0 作成者: Zhou Zhaoxiong
  41. ******************************************************************************/
  42. INT32 メイン()
  43. {
  44. UINT32 iStrType = 0 ;
  45. INT32 iRetVal = 0 ;
  46. INT8 szInputStr[100] = {0};
  47.  
  48. printf("文字列タイプを入力してください(1: 中国語文字列、2: 中国語以外の文字列): \n");
  49. scanf("%d", &iStrType);
  50.      
  51. printf("文字列を入力してください: \n");
  52. scanf("%s", szInputStr);
  53.  
  54. // 入力文字列が中国語文字列か非中国語文字列かを判定する
  55. iRetVal = JudgeStrFormat (szInputStr、iStrType);
  56. (iRetVal != 0) の場合
  57. {
  58. -1 を返します。
  59. }
  60.  
  61. if ( iStrType == 1) // 入力が中国語の文字列の場合、まず各中国語の文字を取得します
  62. {
  63. 中国語文字を取得します(szInputStr);
  64.  
  65. if (giCharNum < = 1) // 1文字だけ入力された場合は直接戻ります
  66. {
  67. printf("%s には文字が 1 つしかありません。確認してください!\n", szInputStr);
  68. -1 を返します。
  69. }
  70. }
  71. そうでない場合 ( iStrType == 2)
  72. {
  73. if (strlen(szInputStr) < = 1) // 1文字だけ入力されたので、直接戻ります
  74. {
  75. printf("%s には文字が 1 つしかありません。確認してください!\n", szInputStr);
  76. -1 を返します。
  77. }
  78. }
  79.   
  80. // 入力文字列が回文かどうかを判定する
  81. 回文文字列を判断します(szInputStr、strlen(szInputStr)、iStrType);
  82.  
  83. 0を返します。
  84. }
  85.  
  86.  
  87. /******************************************************************************************
  88. * 関数の説明: 入力文字列が回文であるかどうかを判定する
  89. * 入力パラメータ: pszInputStr-入力文字列
  90. iInputStrLen - 入力文字列の長さ
  91. iStrType - 入力文字列の型
  92. * 出力パラメータ: なし
  93. * 戻り値: なし
  94. * その他の指示: なし
  95. * 変更日 バージョン番号 修正者 変更内容
  96. * -------------------------------------------------------------------
  97. * 20160222 V1.0 作成者: Zhou Zhaoxiong
  98. ******************************************************************************/
  99. void 判定回文文字列(INT8 *pszInputStr、UINT32 iInputStrLen、UINT32 iStrType)
  100. {
  101. UINT32 iPosFlag = 0 ;
  102.  
  103. if ( NULL == pszInputStr)
  104. {
  105. 戻る;
  106. }
  107.  
  108. if ( iStrType == 1) // 中国語文字列
  109. {
  110. ( iPosFlag = 0 ; iPosFlag <   giCharNum /2; iPosFlag ++)
  111. {
  112. if (strcmp(gszStrCharArray[iPosFlag], gszStrCharArray[giCharNum-1-iPosFlag]) != 0) // 対応する文字が等しくありません
  113. {
  114. printf("%s は回文文字列ではありません!\n", pszInputStr);
  115. 戻る;
  116. }
  117. }
  118. }
  119.  
  120. if ( iStrType == 2) // 中国語以外の文字列
  121. {
  122. // 真ん中から分割し、前後の 2 つの文字を比較します。すべての対応が等しい場合は回文です。
  123. ( iPosFlag = 0 ; iPosFlag <   iInputStrLen /2; iPosFlag++)
  124. {
  125. if (pszInputStr[iPosFlag] != pszInputStr[iInputStrLen-1-iPosFlag]) // 対応する文字が等しくありません
  126. {
  127. printf("%s は回文文字列ではありません!\n", pszInputStr);
  128. 戻る;
  129. }
  130. }
  131. }
  132.  
  133. printf("%s は回文文字列です!\n", pszInputStr);
  134.  
  135. 戻る;
  136. }
  137.  
  138.  
  139. /******************************************************************************************
  140. * 関数の説明: 入力文字列内の各中国語文字を取得します
  141. * 入力パラメータ: pszInputStr-入力文字列
  142. iInputStrLen - 入力文字列の長さ
  143. * 出力パラメータ: なし
  144. * 戻り値: なし
  145. * その他の指示: なし
  146. * 変更日 バージョン番号 修正者 変更内容
  147. * -------------------------------------------------------------------
  148. * 20160222 V1.0 作成者: Zhou Zhaoxiong
  149. ******************************************************************************/
  150. void GetChineseChars(INT8 *pszInputStr)
  151. {
  152. UINT32 iPosFlag = 0 ;
  153.      
  154. if ( NULL == pszInputStr)
  155. {
  156. 戻る;
  157. }
  158.  
  159. memset(gszStrCharArray, 0x00, sizeof(gszStrCharArray));
  160. giCharNum = 0 ;
  161.      
  162. (iPosFlag <   strlen (pszInputStr))
  163. {
  164. snprintf(gszStrCharArray[giCharNum], sizeof(gszStrCharArray[giCharNum])-1, "%c%c", pszInputStr[iPosFlag], pszInputStr[iPosFlag+1]);
  165.  
  166. iPosFlag iPosFlag = iPosFlag + 2; // 各漢字は2バイトを占めます
  167.          
  168. giCharNum++;
  169. }
  170. }
  171.  
  172.  
  173. /******************************************************************************************
  174. * 関数の説明: 入力文字列の形式が正しいかどうかを判定する
  175. * 入力パラメータ: pszInputStr-入力文字列
  176. iStrType - 入力文字列の型
  177. * 出力パラメータ: なし
  178. * 戻り値: 0 - 正しい形式 その他 - 不正な形式
  179. * その他の指示: なし
  180. * 変更日 バージョン番号 修正者 変更内容
  181. * -------------------------------------------------------------------
  182. * 20160222 V1.0 作成者: Zhou Zhaoxiong
  183. ******************************************************************************/
  184. INT32 判定Strフォーマット(INT8 *pszInputStr、UINT32 iStrType)
  185. {
  186. UINT32 iPosFlag = 0 ;
  187.      
  188. if ( NULL == pszInputStr)
  189. {
  190. -1 を返します。
  191. }
  192.  
  193. if ( iStrType == 1) // まず中国語の文字列を決定する
  194. {
  195. ( iPosFlag = 0 ; iPosFlag <   strlen (pszInputStr); iPosFlag++)
  196. {
  197. if (pszInputStr[iPosFlag] > = 0) // 0未満でない場合は、中国語以外の文字が含まれていることを意味します
  198. {
  199. printf("%s には中国語以外の文字が含まれています。確認してください!\n", pszInputStr);
  200. -2 を返します。
  201. }
  202. }
  203. }
  204. else if ( iStrType == 2) // 中国語以外の文字列かどうかをチェックする
  205. {
  206. ( iPosFlag = 0 ; iPosFlag <   strlen (pszInputStr); iPosFlag++)
  207. {
  208. if (pszInputStr[iPosFlag] <   0 ) // 0未満は中国語の文字が含まれていることを意味します
  209. {
  210. printf("%s には中国語の文字が含まれています。確認してください!\n", pszInputStr);
  211. -3 を返します。
  212. }
  213. }
  214. }
  215. それ以外
  216. {
  217. printf("正しい文字列タイプを入力してください!\n");
  218. -4 を返します。
  219. }
  220.  
  221. 0を返します。
  222. }

5. プログラムのテスト

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

1. 中国語の文字列「人上人」を入力すると、プログラムは次のように実行されます。

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 1
  3. 文字列を入力してください:
  4. 最高の
  5. 最高なのは回文文字列です!

2. 中国語の文字列「Who am I」が入力されると、プログラムは次のように実行されます。

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 1
  3. 文字列を入力してください:
  4. 私という人間
  5. 「私は誰ですか?」は回文文字列ではありません。

3. 中国語以外の文字列「level」を入力すると、プログラムは次のように実行されます。

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 2
  3. 文字列を入力してください:
  4. レベル
  5. レベルは回文文字列です!

4. 中国語以外の文字列「good」が入力されると、プログラムは次のように実行されます。

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 2
  3. 文字列を入力してください:
  4. 良い
  5. good は回文文字列ではありません。

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

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 1
  3. 文字列を入力してください:
  4. こんにちは
  5. Hellogoodには中国語以外の文字がありますので、ご確認ください。

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

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 2
  3. 文字列を入力してください:
  4. 良い
  5. 「good好」には漢字がありますので、確認してください。

7. 入力文字列の型が 1 または 2 でない場合、プログラムは次のように実行されます。

  1. 文字列の種類を入力してください (1: 中国語文字列、2: 中国語以外の文字列):
  2. 3
  3. 文字列を入力してください:
  4. グーグ
  5. 正しい文字列タイプを入力してください。

プログラムは、上で検討したいくつかの特殊なケースを正しく処理できることがわかります。

6. 需要拡大

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

1. 入力文字列は、中国語文字列または非中国語文字列のみに限定されず、中国語文字と非中国語文字の混合文字列にすることもできます。

2. 入力文字列が中国語以外の文字列の場合、文字列内の文字数は偶数でなければなりません。つまり、「goog」のような文字列は回文ですが、「level」のような文字列は回文ではありません。

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

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

<<:  [文字列処理アルゴリズム] 文字列を整数に変換するアルゴリズム設計とCコード実装

>>:  [文字列処理アルゴリズム] 最長連続文字とその出現回数のアルゴリズム設計とCコード実装

ブログ    
ブログ    
ブログ    

推薦する

機械学習は「部屋の中の象」に対処するのが難しい

AI には、部屋に突然象が現れたなど、信じられないような異常を発見しながらも、それを冷静に受け入れる...

私たちは皆、AIについて間違っていました! MIT教授が批判:データへの過度の焦点

ルイス・ペレス・ブレバは、マサチューセッツ工科大学 (MIT) の教授であり、MIT エンジニアリン...

Open Interpreterは、大規模な言語モデルのコードをローカルで実行できるようにするオープンソースツールです。

最近、Github を閲覧していたところ、Open Interpreter という魔法のツールを見つ...

自動運転のための強化学習:人間主導の経験ベースのアプローチ

[[428302]] 2021年9月26日にarXivにアップロードされた論文「人間のガイダンスによ...

...

...

ビッグビデオモデルは世界モデルですか? DeepMind/UC Berkeley Chinese: 次のフレームを予測することで世界を変えることができる

今年初めにOpenAIが発表した壮大な傑作「Sora」が、ビデオ関連分野のコンテンツエコロジーを変え...

小紅書探索チームが新たな枠組みを提案:大規模モデル蒸留のためのネガティブサンプルの価値を検証

大規模言語モデル (LLM) はさまざまな推論タスクで優れたパフォーマンスを発揮しますが、ブラックボ...

COVID-19パンデミックの影響を受けて、世界のエッジAIソフトウェア市場は急速な発展を遂げている

MarketsandMarkets は、エッジ AI ソフトウェア市場が 2019 年から 2021...

...

機械学習はバッテリー寿命を予測するのに役立ちます。バッテリーを何回充電できるかを正確に把握できます。

バッテリー寿命の決定は、モバイルハードウェアの開発において重要な部分です。しかし、バッテリーの電気化...

マイクロソフトは、対話してマルチモーダルコンテンツを生成できる AI モデル CoDi をリリースしました。

マイクロソフトは 7 月 11 日にプレスリリースを発行し、Combinable Diffusion...

高校時代の位相除算と位相減算のアルゴリズムについて

[[356850]]プログラミングの本質はアルゴリズムから来ており、アルゴリズムの本質は数学から来て...