?? xreducetestdlg.cpp
字號:
cur_node->num = mask_itemnum[m_idx];
}
//繼續(xù)下一步化簡
ReduceNext( cur_node , pos,maskbit[m_idx][j],mask_itemnum[m_idx] );
}
}
if( high_ok ) break;
}
//根據(jù)自動化簡生成結(jié)果
//編列整個樹
autonum = 0;
if( root.son != NULL ){
SearchAutoRedTree( root.son );
DeleteInvalid();
}
SetCursor( oldcur );
}
void XReduceTestDlg::DeleteInvalid()
{
int min_way,ways,items;
for( int i = 1; i <= autonum; i++ ){
ways = 0;
for( int i1 = 0; i1 < tabAutoReducing[i].intCurIndex ; i1++ ){
items = 0;
for( int i2 = 0; i2 < 17; i2++ ){
if( tabAutoReducing[i].ItemsProcessing[i1][i2] == -1 )
break;
else
items++;
}
switch(items){
case 0: ways += 0; break;
case 1: ways += intValNum; break;
case 2: ways += intValNum-1; break;
case 4: ways += intValNum-2; break;
case 8: ways += intValNum-3; break;
case 16: ways += intValNum-4; break;
}
}
ways += tabAutoReducing[i].intCurIndex - 1 ;
if( i == 1 )
min_way = ways ;
else if( min_way > ways )
min_way = ways;
}
//刪除非最簡方法
for( int i = 1; i <= autonum; i++ ){
ways = 0;
for( int i1 = 0; i1 < tabAutoReducing[i].intCurIndex ; i1++ ){
items = 0;
for( int i2 = 0; i2 < 17; i2++ ){
if( tabAutoReducing[i].ItemsProcessing[i1][i2] == -1 )
break;
else
items++;
}
switch(items){
case 0: ways += 0; break;
case 1: ways += intValNum; break;
case 2: ways += intValNum-1; break;
case 4: ways += intValNum-2; break;
case 8: ways += intValNum-3; break;
case 16: ways += intValNum-4; break;
}
}
ways += tabAutoReducing[i].intCurIndex - 1 ;
if( ways > min_way ){
tabAutoReducing[i] = tabAutoReducing[autonum] ;
autonum--;
i--;
}
}
for( int i = 1; i <= autonum; i++ )
tabAutoReducing[i].Normalize();
//刪除重復(fù)的化簡方法
for( int i = 1 ; i < autonum; i++ ){
for( int j = i+1 ; j <= autonum; j++ ){
if( tabAutoReducing[i] == tabAutoReducing[j] ){
tabAutoReducing[j] = tabAutoReducing[autonum];//刪除該項(xiàng)
autonum--;
// if( j == autonum ) break;
j--;
}
}
}
}
void XReduceTestDlg::SearchAutoRedTree( treeAutoReduce * node )
{
int cur_num;
if( node->son != NULL )//myson
SearchAutoRedTree( node->son );
//找到一個葉節(jié)點(diǎn)
else{
//倒退生成化簡樹
//加入本項(xiàng)
autonum++;//找到葉,就可反向生成一個化簡方法
treeAutoReduce * temp_node = node;
while( temp_node->par != temp_node ){
tabAutoReducing[autonum].AddOneLine(
temp_node->value ,
temp_node->maskbit,
temp_node->num );
temp_node = temp_node->par;
};
if( autonum >= 999 )
DeleteInvalid();
}
if( node->next != NULL )//my brother
SearchAutoRedTree( node->next );
delete node;
}
//原理:需要很大內(nèi)存,不可預(yù)料
/*
void XReduceTestDlg::SearchAutoRedTree( treeAutoReduce * node )
{
int cur_num;
if( node->son != NULL ){//myson
cur_num = autonum;
SearchAutoRedTree( node->son );
//將本項(xiàng)加入所有的現(xiàn)有化簡
for( int i = cur_num+1; i <= autonum ; i++ )
tabAutoReducing[i].AddOneLine( node->value ,node->maskbit ,node->num );
}
//找到一個葉節(jié)點(diǎn)
else{
//加入本項(xiàng)
autonum++;//找到葉,就可反向生成一個化簡方法
tabAutoReducing[autonum].AddOneLine( node->value ,node->maskbit,node->num );
}
if( node->next != NULL )//my brother
SearchAutoRedTree( node->next );
delete node;
}
*/
void XReduceTestDlg::ReduceNext( treeAutoReduce * par , int val, int mask ,int num )
{
int pos = 0;
static int maskbit[4][7] = { {14,13,11,7},{12,10,9,6,5,3},{8,4,2,1},{0} };
//可化簡的項(xiàng)數(shù) 3 2 1
static int mask_num[] = { 4,6,4,1 };//3項(xiàng)化簡:共有四種屏蔽碼
static int mask_itemnum[] = { 8,4,2,1 };
int m_num = intValNum == 3 ? 1 : 0;//與變量數(shù)有關(guān),8
int m_idx = m_num;
int j;
int high_ok = false;//盡量更多項(xiàng)化簡
treeAutoReduce * par_node = par;
treeAutoReduce * cur_node = NULL , * bef_node = NULL;
//刪除上一次化簡所使用的值
static int mask_numl[] = { 0,0x1,0x3,0x7 };
static int mask_numh[] = { 15,12,8,0 };
bool intArrayValue_old[16];
int order;
int t1,t2,t3;
//貽貝恢復(fù)
for( int i = 0; i < 16 ; i++ )
intArrayValue_old[i] = intArrayValue[i];
for( int i = 0; i < num ; i++ ){
order = i;
for( int j = 0; j < intValNum ; 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;
}
}
intArrayValue[order] = false;
}
//刪除上一次化簡所使用的值
//查找第一個
while( !intArrayValue[pos] ) pos++;
if( pos >= 16 ){
//恢復(fù)被刪除的值
for( int i = 0; i < 16 ; i++ )
intArrayValue[i] = intArrayValue_old[i];
return;
}
//取intArrayValue第一項(xiàng)值
for( m_idx = m_num; m_idx <= 3; m_idx++ ){//8項(xiàng),4項(xiàng),2項(xiàng)
for( j = 0; j < mask_num[m_idx]; j++ ){//使用那一個MASK
if( CanReduce( pos,maskbit[m_idx][j],mask_itemnum[m_idx] ) ){
if( high_ok ){//說明同一級存在多種化簡方法
bef_node = cur_node;
cur_node = new treeAutoReduce;
bef_node->next = cur_node;
cur_node->before = bef_node;
cur_node->par = par_node;
cur_node->son = NULL;
cur_node->next = NULL;
cur_node->value = pos;
cur_node->maskbit = maskbit[m_idx][j];
cur_node->num = mask_itemnum[m_idx];
}
else{
high_ok = true;
cur_node = new treeAutoReduce;
par_node->son = cur_node;
cur_node->par = par_node;
cur_node->before = NULL;
cur_node->son = NULL;
cur_node->next = NULL;
cur_node->value = pos;
cur_node->maskbit = maskbit[m_idx][j];
cur_node->num = mask_itemnum[m_idx];
}
//繼續(xù)下一步化簡
ReduceNext( cur_node , pos,maskbit[m_idx][j],mask_itemnum[m_idx] );
}
}
//if( high_ok ) break;//2003_1_7前總是盡量多的項(xiàng)合并,不盡合理
if( high_ok && (m_idx == 2) ) //如果可以多項(xiàng)合并,則不化簡肯定不是最簡
break;//2003_1_7前總是盡量多的項(xiàng)合并,不盡合理
}
//恢復(fù)被刪除的值
for( int i = 0; i < 16 ; i++ )
intArrayValue[i] = intArrayValue_old[i];
}
//能否化簡
bool XReduceTestDlg::CanReduce( int val, int mask ,int num )
{
int mask_numl[] = { 0,0x1,0x3,0x7 };
int mask_numh[] = { 15,12,8,0 };
//檢查相關(guān)項(xiàng)是否也是最小項(xiàng)或無關(guān)項(xiàng)
int order;
int t1,t2,t3;
for( int i = 0; i < num ; i++ ){
order = i;
for( int j = 0; j < intValNum ; 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;
}
}
//判斷是否是最小項(xiàng)
if( intTabValue[order] == 0 ) return false;
}
return true;
}
//未用
void XReduceTestDlg::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
{
if( 10 == nChar )
nChar++;
}
//未用
void XReduceTestDlg::OnKeyUp( UINT nChar, UINT nRepCnt, UINT nFlags )
{
// VK_CONTROL
}
// 正在手工化簡
void XReduceTestDlg::DrawSelfReduingTab( CDC * dc)
{
//若變量還未確定,則不顯示具體數(shù)值,此時顯示沒有意義
if( intProcessState != 2 ) return;
CRect rect,rectBlock = rectDrawArea;
CPoint pt;
rectBlock.DeflateRect( 40,40,0,0 );
int dw = rectBlock.Width() / 4;
int lnum = (intValNum - 2)*2;
int dh = rectBlock.Height() / lnum;
//CString val[3] = { "0","1","X" };
//int tabVal[][4] = { {0,1,3,2},{4,5,7,6},{12,13,15,14},{8,9,11,10} };
int Pos[17][2] = { {1,1},{1,2},{1,4},{1,3},//(行,列)
{2,1},{2,2},{2,4},{2,3},
{4,1},{4,2},{4,4,},{4,3},
{3,1},{3,2},{3,4},{3,3} };
//把已經(jīng)化簡好,用框化出
int line_idx,count;
int data[17];
COLORREF p_col[] = {
RGB(255,0,0), RGB(0,128,0) , RGB(0,128,128), RGB(0,0,255),RGB(128,0,128),
RGB(255,128,64), RGB(255,0,255),RGB(128,128,64),RGB(255,0,128) ,RGB(0,128,255) , RGB(128,0,255),RGB(00,255,0),RGB(128,128,128)
};
CPen * pen;//
CPen * old_pen;
for( line_idx = 0 ; line_idx < tabSelfReducing.intCurIndex ; line_idx++ ){
//取出一行
tabSelfReducing.GetThisLine( line_idx,data, count );
pen = new CPen(PS_SOLID,3,p_col[line_idx%13] );
old_pen = dc->SelectObject( pen );
DrawThisBlock( dc, data, count );
dc->SelectObject( old_pen );
delete pen;
//
}
tabSelfReducing.GetThisLine( tabSelfReducing.intCurIndex,data, count );
//正在化簡的一行顯示色塊
CBrush brush( RGB(255,0,0) );
CBrush * old_brush = dc->SelectObject( &brush );
rectBlock.right = rectBlock.left + dw;
rectBlock.bottom = rectBlock.top + dh;
dc->SetROP2(R2_XORPEN);
for( int i = 0; i < count ; i++ ){
pt.x = (Pos[ data[i] ][1]-1)*dw;
pt.y = (Pos[ data[i] ][0]-1)*dh;
rect = rectBlock + pt;
dc->Rectangle( &rect );
}
dc->SelectObject( old_brush );
}
void XReduceTestDlg::DrawThisBlock(CDC * dc, int * data, int count)
{
//int tabVal[][4] = { {0,1,3,2},{4,5,7,6},{12,13,15,14},{8,9,11,10} };
int Pos[17][2] = { {1,1},{1,2},{1,4},{1,3},//(行,列)
{2,1},{2,2},{2,4},{2,3},
{4,1},{4,2},{4,4,},{4,3},
{3,1},{3,2},{3,4},{3,3} };
int lno_count = 0;//分布于幾行中
bool lno[5];
bool ano[5];
int ano_count = 0;//分布于幾列中
int j,line,array;
for( j = 1 ; j <= 4; j++ ){
ano[j] = false;
lno[j] = false;
}
//統(tǒng)計(jì)分布情況
for( int i = 0 ; i < count; i++ ){
if( !lno[ Pos[data[i]][0] ] ){
lno[ Pos[data[i]][0] ] = true;
lno_count++;
}
if( !ano[ Pos[data[i]][1] ] ){
ano[ Pos[data[i]][1] ] = true;
ano_count++;
}
}
//根據(jù)統(tǒng)計(jì)進(jìn)行分類
CRect rectBlock = rectDrawArea;
rectBlock.DeflateRect( 40,40,0,0 );
int dw = rectBlock.Width() / 4;
int lnum = (intValNum - 2)*2;
int dh = rectBlock.Height() / lnum;
rectBlock.right = rectBlock.left + dw;
rectBlock.bottom = rectBlock.top + dh;
CPoint pt,center;
CRect rect;
if( 1 == count ){
for( line = 1 ; line <= 4; line++ )
if( lno[line] ) break;
for( array = 1 ; array <= 4; array++ )
if( ano[array] ) break;
rect = rectBlock; pt.x = dw*(array-1); pt.y = dh*(line-1); rect += pt;
center = rect.CenterPoint(); pt = center;
pt.y = center.y + 10; center.y -= 10;
dc->Arc( &rect,center,center );
}
//全部同行
else if( 1 == lno_count ){
for( line = 1 ; line <= 4; line++ )
if( lno[line] ) break;
//不相臨列,只有可能:2個選擇項(xiàng),同時分布在1,4列
if( (2 == count) && (ano[1]&&ano[4]) ){
//化兩個半圓
rect = rectBlock; pt.x = 0; pt.y = dh*(line-1); rect += pt;
center = rect.CenterPoint(); pt = center;
pt.y = center.y + 10; center.y -= 10;
dc->Arc( &rect,pt,center );
rect = rectBlock; pt.x = dw*3; pt.y = dh*(line-1); rect += pt;
center = rect.CenterPoint(); pt = center;
pt.y = center.y + 10; center.y -= 10;
dc->Arc( &rect,center,pt );
}
//相臨列
else{
for( j = 1 ; j <= 4; j++ )
if( ano[j] ) break;
rect = rectBlock;
pt.x = dw*(j-1); pt.y = dh*(line-1);
rect += pt;
center = rect.CenterPoint(); pt = center;
pt.y = center.y + 10; center.y -= 10;
dc->Arc( &rect,center,pt );
rect = rectBlock;
pt.x = dw*(j + count -2); pt.y = dh*(line-1);
rect += pt;
center = rect.CenterPoint(); pt = center;
pt.y = center.y + 10; center.y -= 10;
dc->Arc( &rect,pt,center );
//畫直線
dc->MoveTo( rectBlock.left + dw*(j-1) +dw/2,rectBlock.top + dh*(line-1) );
dc->LineTo( rectBlock.left + dw*(j+count-2) +dw/2,rectBlock.top + dh*(line-1) );
dc->MoveTo( rectBlock.left + dw*(j-1) +dw/2,rectBlock.top + dh*line );
dc->LineTo( rectBlock.left + dw*(j+count-2) +dw/2,rectBlock.top + dh*line );
}
}
//全部同列
else if( 1 == ano_count ){
for( line = 1 ; line <= 4; line++ )
if( ano[line] ) break;
//不相臨行,只有可能:2個選擇項(xiàng),同時分布在1,4行
if( (2 == count) && (lno[1]&&lno[4]) ){
//化兩個半圓
rect = rectBlock; pt.y = 0; pt.x = dw*(line-1); rect += pt;
center = rect.CenterPoint(); pt = center;
pt.x = center.x + 10; center.x -= 10;
dc->Arc( &rect,center,pt );
rect = rectBlock; pt.y = dh*3; pt.x = dw*(line-1); rect += pt;
center = rect.CenterPoint(); pt = center;
pt.x = center.x + 10; center.x -= 10;
dc->Arc( &rect,pt,center );
}
//相臨行
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -