一次失败的课设——逻辑函数化简

写在前面

首先感谢我的舍友吴思滢同学,在设计之初我们进行了思路上的探讨,所以这个程序能得以实现也得益于她的启发和帮助。

这个大作业前前后后做了几个月,在这期间我对实现方式改了又改,string数组总是导致报错,即使到了课程快结束时,仍有一些问题没能顺利解决,所以为了不影响整体的功能,最后只能用最原始的枚举特殊情况的方法解决问题了,这也是一个遗憾。

通过这个大作业,也让我对”编程”二字有了新的认识,如何用编程实现一个实际的、具体的问题,与解决C++辅导书里的例题的方式真的相差甚远。

借此感谢老师这学期以来的教学和辅导,每次课后总是耐心解答我的许多问题,我也感受到了数电在逻辑上的魅力。

设计优缺点评价

优点:

①使用类,用户引导好,main函数简单

②输入出错时会产生提示,让用户重新输入

缺点:

①由于使用string数组过程中因内存问题频繁报错,始终没能解决,最后只能使用繁琐且笨的方法解决特殊情况

②用户需要使用最小项下标的二进制数进行输入,比较繁琐

代码部分

一坨答辩

//为了方便测试,设置成了四变量卡诺图化简的形式,实际可根据需要调整
#include <iostream>
#include <string>
using namespace std;
// Kmap类
class Kmap {
public:
    int merged_count=0;
    int count_1[16] = {0};
    int count_2[16] = {0};
    int index=0;
    string original_part[17];
    string merged_part[16][16];
    string combined_part[16][16];
    string simplified_part[16][16];
    void input();
    void count();
    void merge();
    void combine();
    void simplify();
    void combine1();
    void printCombined();
};
// 原始数据的输入
void Kmap::input() {
    cout << "你好!这是我的数电大作业:逻辑函数化简" << endl;
    cout<< "         作者:杨语希    "<<endl;
    cout<<"个人能力所限,做得比较粗糙,请多原谅" << endl;
    cout << endl;
    cout<<"***************************************"<<endl;
    cout<<"*                                     *"<<endl;
    cout<<"* 输入最小项对应的二进制数,输入a结束  *" << endl;
    cout << "*                                     *" << endl;
    cout<<"***************************************"<<endl;
    cout << endl;
    cout <<"请在此输入最小项对应的 4 位二进制数,以空格或回车分隔,如: 0011"<<endl;
    int i = 0;
    while (true) {
        string str;
        cin >> str;
        if (str == "a") {
            break;
        }
        if (str.length() != 4) {
			cout<<"您的输入有误,请重新输入"<<endl;
			continue;
		}
        original_part[i] = str;
        i++;
    }
}
// 统计original_part每个字符串中"1"的个数
void Kmap::count() {
    int i = 0;
    while (original_part[i] != "") {
        int temp = 0;
        for (int j = 0; j < original_part[i].length(); j++) {
            if (original_part[i][j] == '1') {
                temp++;
            }
        }
        count_1[i] = temp;
        i++;
    }
}
// count_1数量相同的元素合并到merged_part中
void Kmap::merge() {
    int i = 0;
    while (original_part[i] != "") {
        int temp = count_1[i];
        int j = 0;
        while (merged_part[temp][j] != "") {
            j++;
        }
        merged_part[temp][j] = original_part[i];
        i++;
    }
    merged_count = i;
}
// 合并相同数量的最小项
void Kmap::combine() {
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            int diffCount = 0;
            string result = "";
            int maxLength = min(merged_part[i][j].length(), merged_part[i + 1][j].length());
            for (int k = 0; k < maxLength; k++) {
                if (merged_part[i][j][k] == merged_part[i + 1][j][k]) {
                    result += merged_part[i][j][k];
                }
               
                else {
                    result += '-';
                    diffCount++;
                }
            }
            if (diffCount <= 1) {
                combined_part[i][j] = result;
            }

        }
    }
}
// 合并相邻的最小项(函数汇总)
void Kmap::simplify() {
    input();
    count();
    merge();
    combine();
    combine1();
}
// 打印输出
void Kmap::printCombined() {
    cout << endl;
    cout << "***************************************" << endl;
    cout << "化简后的结果为:" << endl;
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            if (combined_part[i][j] != "") {
                string term = "";
                for (int k = 0; k < 4; k++) {
                    if (combined_part[i][j][k] == '1') {
                        term += 'A' + k;
                    }
                    else if (combined_part[i][j][k] == '0') {
                        term += 'a' + k;
                    }
                }
                if (term != "")
                    cout << term;
                else if(term=="")
                    cout << "请检查您的输入是否有误,或者您的输入不足以化简";
                if (combined_part[i+1][j]!="" || combined_part[i+2][j]!="" || combined_part[i+3][j] != "" || combined_part[i][j+1] != "" || combined_part[i][j+2] != "" || combined_part[i][j+3] != "" || combined_part[i+1][j+1] != "" || combined_part[i+2][j+1] != "" || combined_part[i+3][j+1] != "" || combined_part[i+1][j-1] != "" || combined_part[i+2][j-1] != "" || combined_part[i+3][j-1] != "") {
                    cout << "+";
                }
            }
        }
    }
    cout << endl;
    cout << "***************************************" << endl;
}

//主函数
int main() {
    Kmap kmap;
    kmap.simplify();
    kmap.printCombined();
    return 0;
}

//代码的不足之处,8个或16个相邻的部分的处理(琢磨了很久总是报错,最后只能用这种笨方法解决,希望老师能够原谅)
void Kmap::combine1() {
    for (int i = 0; i < 16; i++) {
        for (int j = 0; j < 16; j++) {
            if (combined_part[i][j] == "000-" && combined_part[i + 1][j] == "00-1")
            {
                combined_part[i][j] = "00--";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "010-" && combined_part[i + 1][j] == "01-1")
            {
                combined_part[i][j] = "01--";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "100-" && combined_part[i + 1][j] == "10-1")
            {
                combined_part[i][j] = "10--";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "110-" && combined_part[i + 1][j] == "11-1")
            {
                combined_part[i][j] = "11--";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "0-00" && combined_part[i + 1][j] == "-100")
            {
                combined_part[i][j] = "--00";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "0-01" && combined_part[i + 1][j] == "-101")
            {
                combined_part[i][j] = "--01";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "0-10" && combined_part[i + 1][j] == "-110")
            {
                combined_part[i][j] = "--10";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "0-11" && combined_part[i + 1][j] == "-111")
            {
                combined_part[i][j] = "--11";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "000-" && combined_part[i + 1][j] == "--01")
            {
                combined_part[i][j] = "--0-";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "001-" && combined_part[i + 1][j] == "--11")
            {
                combined_part[i][j] = "--1-";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "00--" && combined_part[i + 1][j] == "0-11")
            {
                combined_part[i][j] = "0---";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "1-00" && combined_part[i + 1][j] == "11--")
            {
                combined_part[i][j] = "1---";
                combined_part[i + 1][j] = "";
            }
            else if (combined_part[i][j] == "00--" && combined_part[i + 2][j] == "--11")
            {
                combined_part[i][j] = "----";
                combined_part[i + 1][j] = "";
            }
        }
    }
}