?? xreducetestdlg.h
字號:
#pragma once
#include "atltypes.h"
#include "afxtempl.h"
//存儲化簡步驟
class XTabDataManager
{
public:
int ItemsProcessing[17][17];//{ {1,2,3,-1},{4,2} };
int intCurIndex;//表示目前正在進行第幾次化簡
int intCurItemNum;//目前使用的
int ItemNumber;
int intVarNum;
bool auto_self;
//兩種化簡方法是否完全一致
bool operator ==( XTabDataManager t )
{
//判斷
if( this->intCurIndex != t.intCurIndex )
return false;
bool ItemsOccur[17];
bool ItemsOccur_t[17];
int equal_num = 0;
for( int i = 0; i < intCurIndex ; i++ ){//掃描自己每一行
for( int j = 0; j < 17 ; j++ )
ItemsOccur[j] = false;
for( int j = 0; j < 17 ; j++ ){
if( ItemsProcessing[i][j] != -1 )
ItemsOccur[ ItemsProcessing[i][j] ] = true;
}
for( int ii = 0; ii < intCurIndex ; ii++ ){//掃描對方每一行
for( int j = 0; j < 17 ; j++ )
ItemsOccur_t[j] = false;
for( int j = 0; j < 17 ; j++ ){
if( t.ItemsProcessing[ii][j] != -1 )
ItemsOccur_t[ t.ItemsProcessing[ii][j] ] = true;
}
//兩者比較
for( int j = 0; j < 17 ; j++ )
if( ItemsOccur_t[j] != ItemsOccur[j] )
break;
//找到完全一致行
if( j >= 17){
equal_num++;
break;
}
}
}
return equal_num == intCurIndex;
}
void operator = ( XTabDataManager t )
{
for( int i = 0; i < 17; i++ )
for( int j = 0; j < 17; j++ )
ItemsProcessing[i][j] = t.ItemsProcessing[i][j];
intCurIndex = t.intCurIndex ;
intCurItemNum = t.intCurItemNum ;
ItemNumber = t.ItemNumber ;
intVarNum = t.intVarNum ;
auto_self = t.auto_self;
}
public:
XTabDataManager(){
Init();
}
//自動化簡
void Normalize()
{
int temp[17];
for( int j = 0; j < intCurIndex/2; j++ ){
for( int i = 0; i < 17; i++ )
temp[i] = ItemsProcessing[j][i];
for( int i = 0; i < 17; i++ )
ItemsProcessing[j][i] = ItemsProcessing[intCurIndex-j-1][i];
for( int i = 0; i < 17; i++ )
ItemsProcessing[intCurIndex-j-1][i] = temp[i];
}
}
void Init(){
for( int i = 0; i < 17; i++ )
for( int j = 0; j < 17; j++ )
ItemsProcessing[i][j] = -1;
intCurIndex = 0;intCurItemNum = 0;
ItemNumber = 0;
auto_self = false;
}
void AddOneLine( int val, int mask, int num ){//直接加入一行
int mask_numl[] = { 0,0x1,0x3,0x7 };
int mask_numh[] = { 15,12,8,0 };
//檢查相關(guān)項是否也是最小項或無關(guān)項
int order;
int t1,t2,t3;
for( int i = 0; i < num ; i++ ){
order = i;
for( int j = 0; j < intVarNum ; j++ ){
if( !( (mask>>j) & 0x1) ){//如果碰到屏蔽位是 0
t1 = order & mask_numl[j];//低位
t2 = val & (0x1<<j) ;//插入位
t3 = (order<<1) & mask_numh[j];//保留高位
order = t1 | t2 | t3;
}
}
//加入
ChangeThisLine( order );
}
FinishThisLine();
}
void ChangeThisLine( int which ){//向一行中增加或移去一項
bool exist = false;
//該值是否已在隊列中?
for( int i = 0;i < intCurItemNum; i++ ){
if( ItemsProcessing[intCurIndex][i] == which ){
exist = true;
break;
}
}
if( exist ){
//若已經(jīng)存在,則刪除
ItemsProcessing[intCurIndex][i] = ItemsProcessing[intCurIndex][intCurItemNum-1];
ItemsProcessing[intCurIndex][intCurItemNum-1] = -1;
intCurItemNum--;
}
else{
ItemsProcessing[intCurIndex][intCurItemNum] = which;
intCurItemNum++;
}
}
int Check1Countrt( int data )
{
int c = 0;
for( int i = 0; i < intVarNum; i++ ){
if( (data&0x1) ) c++;
data >>= 1;
}
return c;
}
bool CheckNeighbor( int * data, int count )
{
int d[16],c;
int bitnum;
if( 1 == count ) return true;
else if( 2 == count ) bitnum = 1;
else if( 4 == count ) bitnum = 2;
else if( 8 == count ) bitnum = 3;
else if( 16 == count ) bitnum = 4;
else return false;
for( int i = 1 ; i < count; i++ )
d[i-1] = ( (~data[i])&(~data[0]) )| ( data[i]&data[0] );
c = d[0];
for( int i = 1 ; i < count-1; i++ )
c &= d[i];
c = Check1Countrt( c );
if( c >= intVarNum - bitnum ) return true;
return false;
}
//檢查最新化簡步驟.是否包含在別的化簡步驟
bool CheckIncluded()
{
bool exist;
bool include;
for( int i = 0; i < intCurIndex; i++ ){//查詢每個化簡步驟
int j = 0;
include = true;
while( -1 != ItemsProcessing[intCurIndex][j] ){
exist = false;
int k = 0;
while( -1 != ItemsProcessing[i][k] ){
if( ItemsProcessing[i][k] == ItemsProcessing[intCurIndex][j] ){
exist = true;//找到對應(yīng)項
break;
}
k++;
}
if( !exist ){
include = false;//若有找不到的項,說明不包含
break;
}
j++;
}
if( exist ) return true;
}
return false;
}
//檢查最新化簡步驟.是否包含在別的化簡步驟
bool CheckIncluding()
{
bool exist;
bool include;
bool ret = false;
for( int i = 0; i < intCurIndex; i++ ){//查詢每個化簡步驟
int j = 0;
include = true;
while( -1 != ItemsProcessing[i][j] ){
exist = false;
int k = 0;
while( -1 != ItemsProcessing[intCurIndex][k] ){
if( ItemsProcessing[intCurIndex][k] == ItemsProcessing[i][j] ){
exist = true;//找到對應(yīng)項
break;
}
k++;
}
if( !exist ){
include = false;//若有找不到的項,說明不包含
break;
}
j++;
}
if( exist ){
//刪除以前化簡步驟,保證化簡順序不變
j = i;
for( ; j < intCurIndex; j++ ){
for( int ii = 0; ii < 17; ii++ )
ItemsProcessing[j][ii] = ItemsProcessing[j+1][ii];
}
for( int ii = 0; ii < 17; ii++ )
ItemsProcessing[intCurIndex][ii] = -1;
intCurIndex--;
ret = true;
i--;
}
}
return ret;
}
void FinishThisLine(){
//判斷是否能構(gòu)成相臨項
if( 0 == intCurItemNum ) return;
if( ( 1 == intCurItemNum ) || (2 == intCurItemNum) || (4 == intCurItemNum) || (8 == intCurItemNum) || (16 == intCurItemNum));
else{
AfxMessageBox( "只有2的n次方個相臨項才能合并!" );
return;
}
if( !CheckNeighbor( ItemsProcessing[intCurIndex], intCurItemNum ) ){
AfxMessageBox( "無法合并!\n規(guī)則提示:只有相臨項才能合并!" );
return;
}
//檢查是否包含在別的項中
if( CheckIncluded() ){
if( !auto_self )
AfxMessageBox( "已經(jīng)包含在以前的化簡過程中!" );
//清除本次化簡數(shù)據(jù)
for( int i = 0; i < 17; i++ )
ItemsProcessing[intCurIndex][i] = -1;
intCurItemNum = 0;
return;
}
if( CheckIncluding() ){
if( !auto_self )
AfxMessageBox( "包含以前的化簡過程!\n以前的化簡過程將被自動刪除!" );
}
intCurIndex++;
intCurItemNum = 0;//新的一行
}
//根據(jù)用戶化簡步驟,分析化簡的合理性
void AnalsysThisLineRes( int lidx ,int count, int & c)
{
//從本行中找到一個以前化簡中沒有出現(xiàn)的一項,look around about it
//
}
//得到一行化簡結(jié)果:結(jié)果存放在RES中,其中的 1 表示該項必須保留
//DATA:
void GetThisLineRes( int lidx ,int count, int & c)
{
int d[16];
if( 1 == count ){
c = 0xff;
return;
}
for( int i = 1 ; i < count; i++ )
d[i-1] = ( (~ItemsProcessing[lidx][i])&(~ItemsProcessing[lidx][0]) )|
( ItemsProcessing[lidx][i]&ItemsProcessing[lidx][0] );
c = d[0];
for( int i = 1 ; i < count-1; i++ )
c &= d[i];
}
bool GetThisLine( int lidx, int * data, int & count ){
if( lidx > intCurIndex ) return false;
//data = ItemsProcessing[lidx];
count = 0;
for( int i = 0;i < 17; i++ ){
if( ItemsProcessing[lidx][i] != -1 )
count++;
else break;
data[i] = ItemsProcessing[lidx][i];
}
}
//檢查是否已將所有的項都包含
bool CheckAll( int * data )
{
bool exist[17];
int i,j;
int total = intVarNum == 3 ? 8 : 16;
for( i = 0; i < 17; i++ )
exist[i] = false;
for( i = 0; i < intCurIndex; i++ ){
j = 0;
while( -1 != ItemsProcessing[i][j] ){
exist[ ItemsProcessing[i][j] ] = true;
j++;
}
}
for( i = 0; i < 16; i++ ){
if( 1 == data[i] ){
if( !exist[i] ) return false;
}
}
return true;
}
};
struct treeAutoReduce
{
treeAutoReduce * before;
treeAutoReduce * next;
treeAutoReduce * son;
treeAutoReduce * par;
int value;
int maskbit;
int num;
};
// XReduceTestDlg 對話框
class XReduceTestDlg : public CDialog
{
DECLARE_DYNAMIC(XReduceTestDlg)
public:
XReduceTestDlg(CWnd* pParent = NULL); // 標準構(gòu)造函數(shù)
virtual ~XReduceTestDlg();
// 對話框數(shù)據(jù)
enum { IDD = IDD_PRACTICE };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
BOOL OnInitDialog(void);
private:
// 變量個數(shù)
int intValNum;
// 是否允許輸入無關(guān)項
BOOL bHaveIgnoreItem;
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnLButtonDown( UINT, CPoint );
afx_msg void OnRButtonDown( UINT, CPoint );
afx_msg void OnPaint();
afx_msg void OnKeyDown( UINT, UINT, UINT );
afx_msg void OnKeyUp( UINT, UINT, UINT );
afx_msg void OnTimer( UINT );
protected:
void DrawBlockTitle( CDC * );
public:
// 繪圖區(qū)域
CRect rectDrawArea;
// 目前處理狀態(tài):設(shè)置、添表、化簡、檢查、自動演示
int intProcessState;
int old_state;
// 顯示表格中的數(shù)值
int intTabValue[16];
// 顯示化簡過程以及化簡結(jié)果
int curProcess;
// 定時器
UINT_PTR m_timer;
bool timer_on;
// 手工化簡過程:幾個最小項
XTabDataManager tabSelfReducing;
// 自動化簡:幾個最小項
XTabDataManager * tabAutoReducing;//自動化簡后
int use_num;//debug
int autonum;//共有幾種化簡方法
int cur_autonum;//共有幾種化簡方法
bool intArrayValue[16];//隊列中剩余1的位置
int intArrayNum;
treeAutoReduce root;
//判斷化簡方法是否一致
bool CheckReduceOK();
//自動化簡
void DeleteInvalid();
void SearchAutoRedTree( treeAutoReduce * par );
bool CanReduce( int val, int mask ,int item_num );
void ReduceNext( treeAutoReduce * par , int val, int mask ,int item_num );
void AutoReduce();
void DrawTabData( CDC * );
// 檢測鼠標的位置
int PointInWhichTab(CPoint poi, CRect & rect);
void ChangeTabVal( int order );
afx_msg void OnBnClickedButton4();
// 正在手工化簡
void DrawSelfReduingTab(CDC *dc);
void DrawThisBlock(CDC * dc, int * data, int count);
afx_msg void OnBnClickedButton5();
afx_msg void OnBnClickedButton6();
afx_msg void OnBnClickedButton7();
// 顯示化簡結(jié)果
CString csReduceResult;
void DrawSelfReduingProcess(CDC * dc);
afx_msg void OnBnClickedButton8();
afx_msg void OnBnClickedButton11();
afx_msg void OnBnClickedButton12();
afx_msg void OnBnClickedButton9();
afx_msg void OnBnClickedButton13();
};
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -