データ構造計算機実験報告


一、実験目的と要求
1.計算機の設計と実装.
要求:授業後作業-03、授業後作業-05の作業内容に基づいて(1)グラフィックインタラクティブ機能を追加する.(2)論理演算子を3つ追加&&,|,!論理演算子と算術演算子の混合演算を処理することができます.(3)フォールトトレランス機能を追加し,異常処理を行うことができる.
二、実験環境
Qt 5.9
三、実験内容
レッスン後ジョブ-03、レッスン後ジョブ-05のジョブ内容に加えて(1)グラフィックインタラクション機能を追加する.(2)論理演算子を3つ追加&&,|,!論理演算子と算術演算子の混合演算を処理することができます.(3)フォールトトレランス機能を追加し,異常処理を行うことができる.
四、実験過程
実験中の分析、設計作業を文字、図(フローチャートなど)、表などで記録する.
4.1タスク定義と問題分析
                 ,       ,                。
            ,      MFC  ,      Qt     ,    Qt  。
          ,                     ,      。

4.2データ構造の選択と概要設計
        
                ,       QString line      ,        ,         line ,      ,            ,      ,    。

4.3詳細設計
1.入力式
	           line ,  void add_and_update()  ,            ,             ,  sender()                ,          line 。

2.入力式の計算
	                  , ‘=’        void add_and_update() void caculate(),        ,    void add_and_update() ‘#’   line ;   void caculate()     。

3.許容誤差
	      ,         ,                 。
	      ,          ,      ,    。
	     ,   num    char_n       ,      ,    。

4.論理演算子の計算:
	                 ;
	        ,     “!” , num      ,    。

QString line; 計算に使用する式を保存します.QString line0; 表示する式を保存します.QString history; 正しく計算された式を保存して表示します.QStack char_n; 文字を保存します.QStack num; 数値を保存します.QString s; 計算時にlineに値を割り当てます.double result; 最後に計算した結果.void add_and_update(); 演算子をlineに追加します.void caculate(); 式を計算します.bool check(); 式に誤りがないかどうかを確認します.int getindex(char i); 対応する文字の下付き文字を取得します.char getpriority(char i, char j); 文字の優先度は、下付き文字で取得します.int hextobin(int i,int* n); 10進数を2進数に変換します.int bintohex(int*p,int j)は、バイナリ数を10進数に変換します.int or_num(int j,int k); 1,0に対して、または演算を行います.int and_num(int j,int k); 1,0を演算します.int o_r(int j,int k); 2つの10進数に対してまたは演算を行います.int a_nd(int j,int k); 2つの10進数を演算します.double caculator(char i, double j, double k);両目演算子の計算
五、テストと結果分析
各種のデータに対してプログラムとアルゴリズムの結果を実行して記録して分析して、そして誤りに対して行った修正と結果.
5.1実験データ
1+8/4-1! 5|8 9&(5+3) 9&1! 5.83.2-3 9/(4+8-12) 8-5
5.2結果及び分析
六、実験収穫
   Qt   , Qt           

七、付録(ソースコード)
widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include 

namespace Ui {
     
class Widget;
}

class Widget : public QWidget
{
     
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
protected slots:
    void add_and_update();
    void caculate();
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H



main.h
#include "widget.h"
#include 

int main(int argc, char *argv[])
{
     
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}


widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
#include
#include
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
     
    ui->setupUi(this);
    connect(ui->number0,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number1,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number2,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number3,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number4,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number5,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number6,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number7,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number8,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->number9,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->jia,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->jian,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->cheng,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->chu,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->zuokuohao,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->youkuohao,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->dengyu,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->dengyu,SIGNAL(clicked(bool)),this,SLOT(caculate()));
    connect(ui->c,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->shanchu,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->And,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->Not,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->Or,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->dian,SIGNAL(clicked(bool)),this,SLOT(add_and_update()));
    connect(ui->clearhistory,SIGNAL(clicked(bool)),this,SLOT(clear()));
    setFixedSize(this->width(),this->height());//        
}
Widget::~Widget()
{
     
    delete ui;
}
QString line;
QString line0;
QString history;
QStack<char> char_n;
QStack<double> num;
QString s;
double result;
bool check()
{
     
    QString error[8]={
     "/","*","+","-","&","|",")","!"};
    QString error2[67]={
     "|&","&|","!|","!&","&-","&+","&*","&/","|+","|-","|*","|/","+&","+|","-&","-|","/|",
                        "/&","*&","*|","/*","*/","+-","-+","/-","-/","+/","/+","*+","+*","-*","*-","-)","(-",
                        "(+","+)","/)","(/","*)","(*","+-","-+","--","++","//","**","&&","||","!!","-.","+.",
                        "/.","*.","!.","&.","|.",".-",".+","./",".*",".!",".&",".|",".(",".)","(.",")."};
    for(int i=0;i<8;i++)
        if(line0.startsWith(error[i]))
            return false;
    for(int i=0;i<67;i++)
        if(line0.contains(error2[i],Qt::CaseSensitive))
            return false;
    return true;
}
int getindex(char i)
{
     
    switch (i)
    {
     
    case '+':
            return 0;
        case '-':
            return 1;
        case '*':
            return 2;
        case '/':
            return 3;
        case '(':
            return 4;
        case ')':
            return 5;
        case '&':
            return 6;
        case '|':
            return 7;
        case '#':
            return 8;
        default:
            return -1;
    }
}
char getpriority(char i, char j)
{
     
    const char data[][9] =
           {
     
               {
     '>', '>', ', ', ', '>', '>', '>', '>'},
               {
     '>', '>', ', ', ', '>', '>', '>', '>'},
               {
     '>', '>', '>', '>', ', '>', '>', '>', '>'},
               {
     '>', '>', '>', '>', ', '>', '>', '>', '>'},
               {
     ', ', ', ', ', '=', ', ', '0'},
               {
     '>', '>', '>', '>', '0', '>', '>', '>', '>'},
               {
     ', ', ', ', ', '>', '>', '>', '>'},
               {
     ', ', ', ', ', '>', ', '>', '>'},
               {
     ', ', ', ', ', '0', ', ', '='},
           };
    int c = getindex(i);
    int d = getindex(j);
    return data[c][d];
}
int hextobin(int i,int* n)
{
     
    int j = 0;
    while (i)
    {
     
        n[j] = i % 2;
        i /= 2;
        j++;
    }
    return j;
}
int or_num(int j,int k)
{
     
    if (j==1||k==1)
    {
     
        return 1;
    }
    return 0;
}
int and_num(int j,int k)
{
     
    if (j==1&&k==1)
    {
     
        return 1;
    }
    return 0;
}
int bintohex(int *p,int j)
{
     
    int n = 0;
    for (int i = 0; i < j; i++)
    {
     
        if (p[i]==1)
            n += pow(2, i);
    }
    return n;
}
int o_r(int j,int k)
{
     
    int n1[1000]={
     0}, n2[1000]={
     0};
    int pos = hextobin(j, n1);
    int pos2 = hextobin(k, n2);
    if(pos>=pos2)
        pos2=pos;
    else {
     
        pos=pos2;
    }
    int num[pos];
    int h = 0;
    for (int i = 0; i <pos; i++)
    {
     
        num[h] = or_num(n1[i], n2[i]);
        ++h;
    }
    return bintohex(num,pos);
}
int a_nd(int j,int k)
{
     
    int n1[1000]={
     0}, n2[1000]={
     0};
    int pos = hextobin(j, n1);
    int pos2 = hextobin(k, n2);
    if(pos>=pos2)
        pos2=pos;
    else {
     
        pos=pos2;
    }
    int num[pos];
    int h = 0;
    for (int i = 0; i <pos; i++)
    {
     
        num[h] = and_num(n1[i], n2[i]);
        ++h;
    }
    return bintohex(num,pos);
}
double caculator(char i, double j, double k)
{
     
    switch (i)
    {
     
    case '+':
        return j + k;
    case '-':
        return j - k;
    case '*':
        return j * k;
    case '/':
        if(k==0)
            return 1e10;
        return j / k;
    case '|':
        return o_r(j,k);
    case '&':
        return a_nd(j,k);
    default:
        return 1e10;
    }
}

void Widget::caculate()
{
     
    if(!check())
        QMessageBox::critical(this,"  ","        !");
    else
    {
     
    int i = 0;
    char_n.push('#');
    while (!s.isEmpty())
    {
     
        double data = 0;
        bool is_data=false;
        while (s[i].isDigit())
        {
     
            is_data=true;
            QString m=s.mid(0,1);
            data = data * 10 + m.toInt();
            s.remove(0,1);
            if(s[i]==".")
            {
     
                s.remove(0,1);
                int pos=0;
                int dex=0;
                while (s[i].isDigit())
                {
     
                    QString mn=s.mid(0,1);
                    pos = pos * 10 + mn.toInt();
                    dex++;
                    s.remove(0,1);
                }
                data+=pos/pow(10,dex);
            }
        }

        if (is_data)
            num.push(data);
        if (s[i]=='!')
        {
     
            s.remove(0,1);
            data=num.top();
            num.pop();
            num.push(!data);
         }
        if (!s[i].isDigit() )
        {
     
            char b = char_n.top();
            char priority;
            QString m=s.mid(0,1);
            QChar *n=new QChar[1];
            n=m.data();
            char l;
            l=n->toLatin1();
            priority = getpriority(b, l);
            switch (priority)
            {
     
            case ':
                char_n.push(l);
                s.remove(0,1);
                break;
            case '=':
                char_n.pop();
                s.remove(0,1);
                break;
            case '>':
                double q = num.top();
                num.pop();
                if(num.empty())
                {
     
                    QMessageBox::critical(this,"  ","        !");
                    return;
                }
                double w = num.top();
                num.pop();
                if(caculator(b, w, q)!=1e10)
                    num.push(caculator(b, w, q));
                else
                {
     
                    QMessageBox::warning(this,"  ","      !");
                    return;
                }
                char_n.pop();
                break;
            }
        }
    }
    result = num.top();
    num.pop();
    history+=line;
    history+="=";
    history+=(QString::number(result));
    history+="
"
; ui->textBrowser->setText(history); ui->lineEdit->setText(QString::number(result)); } } void Widget::add_and_update() { QPushButton *object=qobject_cast<QPushButton *>(sender()); QString name=object->objectName(); if(name=="number1") { line+="1"; line0+="1"; ui->label->setText(line); } if(name=="number2") { line+="2"; line0+="2"; ui->label->setText(line); } if(name=="number3") { line+="3"; line0+="3"; ui->label->setText(line); } if(name=="number4") { line+="4"; line0+="4"; ui->label->setText(line); } if(name=="number5") { line+="5"; line0+="5"; ui->label->setText(line); } if(name=="number6") { line+="6"; line0+="6"; ui->label->setText(line); } if(name=="number7") { line+="7"; line0+="7"; ui->label->setText(line); } if(name=="number8") { line+="8"; line0+="8"; ui->label->setText(line); } if(name=="number9") { line+="9"; line0+="9"; ui->label->setText(line); } if(name=="number0") { line+="0"; line0+="0"; ui->label->setText(line); } if(name=="chu") { line0+="/"; line+="÷"; ui->label->setText(line); } if(name=="cheng") { line0+="*"; line+="×"; ui->label->setText(line); } if(name=="jia") { line+="+"; line0+="+"; ui->label->setText(line); } if(name=="jian") { line+="-"; line0+="-"; ui->label->setText(line); } if(name=="And") { line+="&&"; line0+="&"; ui->label->setText(line); } if(name=="Not") { line+="!"; line0+="!"; ui->label->setText(line); } if(name=="Or") { line+="||"; line0+="|"; ui->label->setText(line); } if(name=="zuokuohao") { line+="("; line0+="("; ui->label->setText(line); } if(name=="youkuohao") { line+=")"; line0+=")"; ui->label->setText(line); } if(name=="dian") { line+="."; line0+="."; ui->label->setText(line); } if(name=="shanchu") { line.chop(1); line0.chop(1); ui->label->setText(line); } if(name=="c") { line=line0=""; ui->label->setText(line); ui->lineEdit->setText(""); } if(name=="dengyu") { s=line0+"#"; } } void Widget::clear() { history=""; ui->textBrowser->setText(history); }