1. 程式人生 > 其它 >實驗三 串及應用

實驗三 串及應用

實驗內容

  1. 編寫程式,實現串的樸素的模式匹配演算法;基於此模式匹配演算法(教科書演算法4.5),統計某子串在主串中出現的次數。
  2. 編寫程式,統計在輸入字串中各個不同字元出現的頻度並將結果存入檔案(字串中的合法字元為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>

  軟體截圖: