實驗三 串及應用
阿新 • • 發佈:2021-11-10
實驗內容
- 編寫程式,實現串的樸素的模式匹配演算法;基於此模式匹配演算法(教科書演算法4.5),統計某子串在主串中出現的次數。
- 編寫程式,統計在輸入字串中各個不同字元出現的頻度並將結果存入檔案(字串中的合法字元為A-Z這26個字母和0-9這10個數字)。(提示:由於字母共26個,加上數字符號10個共36個,所以設一長36的整型陣列,前10個分量存放數字字元出現的次數,餘下存放字母出現的次數。)
實驗程式碼及截圖
0.標頭檔案及其基本定義
#include <malloc.h> #include <stdio.h> #include <stdlib.h> #include<cstdlib> #include <string.h> #include <iostream> using namespace std; #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define INFEASIBLE -1 #define OVERFLOW -2 #define MAXSTRLEN 255 typedef int Status; //順序串的定義 typedef struct {char ch[MAXSTRLEN + 1]; int length; }SString; void CreatSString(SString &S) { gets_s(S.ch); S.length = strlen(S.ch); }
1.樸素的模式匹配演算法的實現
//樸素模式匹配演算法 int Index(SString S, SString T, int pos) { int k = pos; int i = k; int j = 0; while (i <= S.length && j <= T.length) {if (S.ch[i] == T.ch[j]) { i++; j++; } else { k++; i = k; j = 0; } if (j >= T.length) { return k; } } return -1; }
2.統計子串的個數
//統計某子串在主串中出現的次數 int IndexCount(SString S, SString T) { int k = 0, i = 0,pos = 0; while (pos != -1) { pos = Index(S, T, k); k = pos + T.length; i++; } return i-1; }
3.統計在輸入字串中各個不同字元出現的頻度並將結果存入檔案
//統計在輸入字串中各個不同字元出現的頻度並將結果存入檔案 int* AllIndexCount(SString S) { int* temp = new int[36]; for (int k = 0; k < 36; k++) { temp[k] = 0; } int pos; for (pos = 0; pos < S.length; pos++) { for (int i = 0; i < 10; i++) { if (S.ch[pos] == 48 + i) { temp[i]++; break; } } for (int i = 0; i < 26; i++) { if (S.ch[pos] == 65 + i) { temp[10 + i]++; break; } } } return temp; } //陣列的遍歷 void dispArr(int* arr, int n) { printf("該字串中出現了\n"); for (int i = 0; i < n; i++) { static char k = 0; if (i < 10 && arr[i] != 0) { k = i + 48; printf("%c:%d\n", k, arr[i]); } else if (arr[i] != 0) { k = i + 55; printf("%c:%d\n", k, arr[i]); } } } //檔案儲存時陣列的遍歷 void FileDispArr(int* arr, int n, FILE* fpWrite) { fprintf(fpWrite, "該字串中出現了\n"); for (int i = 0; i < n; i++) { static char k = 0; if (i < 10 && arr[i] != 0) { k = i + 48; fprintf(fpWrite, "%c:%d\n", k, arr[i]); } else if (arr[i] != 0) { k = i + 55; fprintf(fpWrite, "%c:%d\n", k, arr[i]); } } }
4.主程式(測試時)
int main() { SString s; CreatSString(s); int* arr1; arr1 = AllIndexCount(s); dispArr(arr1, 36); delete arr1; return 0; }
5.主程式(完善了控制檯介面後)
int main() { int operation = 0; printf("\n如果要執行串的操作程式請輸入1,如果想退出請輸入0\n> "); scanf_s("%d", &operation); if (operation == 1) { operation = 0; while (1) { if (operation == 0) { printf("\n\t----------------------------------------------------------\n"); printf("\t輸入對應的值來進行對應的操作\n"); printf("\t----------------------------------------------------------\n"); printf("\t1.統計某子串在主串中出現的次數\n\t2.統計在輸入字串中各個不同字元出現的頻度並將結果存入檔案\n"); printf("\t----------------------------------------------------------\n"); printf("\t-1.退出程式\n"); printf("\t----------------------------------------------------------\n> "); scanf_s("%d", &operation); if (operation != 1 && operation != 2) { operation = -1; } } if (operation == -1) return 0; if (operation == 1) { SString s,m,t; printf("\n請輸入主串\n> "); CreatSString(s); CreatSString(m); printf("\n請輸入子串\n> "); CreatSString(t); int count = IndexCount(m,t); printf("\n主串中出現了%d次子串\n", count); printf("\n\n繼續當前操作請輸入1,返回選單請輸入0\n> "); scanf_s("%d", &operation); if (operation != 0 && operation != 1) { operation = 0; } } if (operation == 2) { SString s,m; printf("\n請輸入要統計的串(僅支援A-Z,0-9)\n> "); CreatSString(m); CreatSString(s); int* arr1; arr1 = AllIndexCount(s); printf("\n"); dispArr(arr1, 36); FILE* fpWrite; int error = 0; error = fopen_s(&fpWrite, "Data.txt", "w+"); if (fpWrite == NULL) return 0; FileDispArr(arr1, 36,fpWrite); printf("\n檔案建立成功,檔名為Data.txt\n"); fclose(fpWrite); delete arr1; printf("\n繼續當前操作請輸入2,返回選單請輸入0\n> "); scanf_s("%d", &operation); if (operation != 0 && operation != 2) { operation = 0; } } } } else { return 0; } }
6.執行截圖
大的來了
做完這次實驗後,我自己摸索了一下QT,用QT將基於這兩個演算法的應用編寫了出來
基本的實現方法與這兩個演算法一致,但我是用的是QT自帶的QString庫來編寫的,所以查詢子串可以查詢中文的子串
部分程式碼及軟體截圖:
mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { QString str,ot; str = ui->textEdit->toPlainText(); int count[126]={}; for(int i=0;i<str.length();i++) { QString x = str.mid(i,1); for(int j = 0;j<126;j++) { QByteArray a; a.resize(1); a[0]=j; QString q; q = a.data(); if(x==q) { count[j]++; break; } } } for(int i=0;i<126;i++) { if(count[i]!=0 && i!=10) { QByteArray a; a.resize(1); a[0]=i; QString q; q = a.data(); ot = ot+"‘"+q+"’"+":"+QString::number(count[i])+"個\t"; } } ui->textBrowser->setText("該字串中\n"+ot); } void MainWindow::on_pushButton_2_clicked() { QString mainStr,childStr; int count=0; mainStr = ui->mainTEdit->toPlainText(); childStr = ui->childTEdit->toPlainText(); for(int i=0;i<mainStr.length()-childStr.length()+1;i++) { QString compareStr; compareStr = mainStr.mid(i,childStr.length()); if(compareStr==childStr) count++; } ui->numTBrown->setText("‘"+childStr+"’"+"出現了"+QString::number(count)+"次"); }
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>601</width> <height>715</height> </rect> </property> <property name="cursor"> <cursorShape>ArrowCursor</cursorShape> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralWidget"> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QGroupBox" name="groupBox"> <property name="font"> <font> <family>獅尾四季春SC-Bold</family> <weight>75</weight> <bold>true</bold> </font> </property> <property name="title"> <string>統計各個字元出現的次數(僅限英文和數字)</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <widget class="QTextEdit" name="textEdit"> <property name="font"> <font> <family>Courier New</family> <pointsize>10</pointsize> <weight>50</weight> <bold>false</bold> </font> </property> <property name="cursor" stdset="0"> <cursorShape>IBeamCursor</cursorShape> </property> </widget> </item> <item> <widget class="QPushButton" name="pushButton"> <property name="font"> <font> <family>思源宋體 Heavy</family> <pointsize>12</pointsize> <weight>75</weight> <bold>true</bold> </font> </property> <property name="text"> <string>統計各個字元出現的次數(僅限英文和數字)</string> </property> </widget> </item> <item> <widget class="QTextBrowser" name="textBrowser"> <property name="font"> <font> <family>等線</family> <pointsize>10</pointsize> <weight>50</weight> <bold>false</bold> </font> </property> <property name="cursor" stdset="0"> <cursorShape>IBeamCursor</cursorShape> </property> </widget> </item> </layout> </widget> </item> <item> <spacer name="verticalSpacer"> <property name="orientation"> <enum>Qt::Vertical</enum> </property> <property name="sizeType"> <enum>QSizePolicy::Fixed</enum> </property> <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>20</height> </size> </property> </spacer> </item> <item> <widget class="QGroupBox" name="translateGroup"> <property name="font"> <font> <family>獅尾四季春SC-Bold</family> <weight>75</weight> <bold>true</bold> </font> </property> <property name="title"> <string>統計子串出現個數</string> </property> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <widget class="QGroupBox" name="mainBox"> <property name="title"> <string>主串</string> </property> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> <widget class="QTextEdit" name="mainTEdit"> <property name="font"> <font> <family>獅尾四季春SC-SemiBold</family> <pointsize>10</pointsize> <weight>75</weight> <bold>true</bold> </font> </property> <property name="cursor" stdset="0"> <cursorShape>IBeamCursor</cursorShape> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QGroupBox" name="childBox"> <property name="title"> <string>子串</string> </property> <layout class="QVBoxLayout" name="verticalLayout_5"> <item> <widget class="QTextEdit" name="childTEdit"> <property name="font"> <font> <family>獅尾四季春SC-SemiBold</family> <pointsize>10</pointsize> <weight>75</weight> <bold>true</bold> </font> </property> <property name="cursor" stdset="0"> <cursorShape>IBeamCursor</cursorShape> </property> </widget> </item> </layout> </widget> </item> <item> <widget class="QPushButton" name="pushButton_2"> <property name="font"> <font> <family>思源宋體 Heavy</family> <pointsize>12</pointsize> </font> </property> <property name="text"> <string>統計子串出現個數</string> </property> </widget> </item> <item> <widget class="QTextBrowser" name="numTBrown"> <property name="sizeIncrement"> <size> <width>0</width> <height>0</height> </size> </property> <property name="font"> <font> <family>獅尾四季春SC-Black</family> <pointsize>12</pointsize> <weight>75</weight> <bold>true</bold> </font> </property> <property name="cursor" stdset="0"> <cursorShape>IBeamCursor</cursorShape> </property> </widget> </item> </layout> </widget> </item> </layout> </widget> <widget class="QMenuBar" name="menuBar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>601</width> <height>26</height> </rect> </property> </widget> <widget class="QToolBar" name="mainToolBar"> <attribute name="toolBarArea"> <enum>TopToolBarArea</enum> </attribute> <attribute name="toolBarBreak"> <bool>false</bool> </attribute> </widget> <widget class="QStatusBar" name="statusBar"/> </widget> <layoutdefault spacing="6" margin="11"/> <resources/> <connections/> </ui>
軟體截圖: