对于TreeControl常用操作,做如下介绍。

1. TreeControl添加节点

  1. 在界面种选择TreeControl控件,点击右键,在弹出的菜单种选择【添加变量】,在弹出的界面中输入变量名 "m_list”

  2. 点击界面右键,在弹出的菜单中选择【类向导】,选中“虚函数”选项卡,选择其中的“OnInitDialog”函数,然后点击【添加函数按钮】,然后点击确定。

  3. 将TreeControl控件中的属性“Has Buttons”、”Line at root“和“Has Line”后改为 “True”,如果相实现双击更改其值的功能,则将”Edit Labels“改为”True“

  4. 如果想要在树节点前添加图标,则需要导入*.icon的图标文件。具体方法为:

    选择资源视图,在资源视图中点击右键,在弹出的菜单中选择【添加资源】,在弹出的界面中点击【导入】按钮,然后选择.icon的文件。此图标导入后的名称为”IDI_ICON1“

  5. 在初始化函数中添加节点代码

//在.h文件中添加如下代码
CImageList m_imageList1;
//修改初始化函数
BOOL TreeTest::OnInitDialog()
{
CDialogEx::OnInitDialog(); m_list.SetBkColor(RGB(230,230,230));//设置树的颜色 m_imageList1.Create(16,16,ILC_COLOR8|ILC_MASK,0,4);//第五个参数为图标的总数
m_imageList1.Add(AfxGetApp()->LoadIconW(IDI_ICON1));//将图标添加到imageList中 m_list.SetImageList(&m_imageList1,TVSIL_NORMAL);//将图标进行加载 HTREEITEM root = m_list.InsertItem(_T("root"));//插入根节点
HTREEITEM hChild1 = m_list.InsertItem(_T("child1"),root);//在根节点下插入子节点
HTREEITEM hChild2 = m_list.InsertItem(_T("child2"),root);//在根节点下插入子节点
HTREEITEM hChild3 = m_list.InsertItem(_T("child3"),root);//在根节点下插入子节点 m_list.SetItemImage(root,0,0);//设置根节点图标
m_list.SetItemImage(hChild1,0,0);
m_list.SetItemImage(hChild2,0,0);
m_list.SetItemImage(hChild3,0,0);//设置子节点图标,注意:第一个参数为要设置的节点、第二个参数为默认状态下的图标、第三个值为选中后的图标。 return TRUE; // return TRUE unless you set the focus to a control }

2. TreeControl菜单

  1. 新建一个菜单,内容为”增加“、”删除“、”重命名“
  2. 选中Tree控件,点击右键,在弹出的菜单中选择”类向导“;在弹出的界面中选择【命令】、对象下选择”IDC_TREE1“,在消息中选择右键消息”NM_RCLICK“,然后点击【添加处理程序】按钮。
  3. 选中节点后才可以加载菜单,具体代码如下:
void TreeTest::OnRclickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
CPoint ScreenPt;
GetCursorPos(&ScreenPt); CPoint pt =GetCurrentMessage()->pt;//获取当前鼠标点击消息的坐标点
m_list.ScreenToClient(&pt);//将鼠标的屏幕坐标,转换成树控件的客户区域坐标
UINT uFlags = 0;
HTREEITEM hItem = m_list.HitTest(pt,&uFlags);//然后做点击测试 /**判断右键是否在节点上**/
if ((hItem != NULL)&&(TVHT_ONITEM & uFlags))//如果点击位置在界面位置上面
{ CMenu menu;
menu.LoadMenuW(IDR_MENU1);//装载第一个子菜单,即我们菜单的第一列
CMenu* pPopup = menu.GetSubMenu(0);
pPopup->TrackPopupMenu(TPM_LEFTALIGN, ScreenPt.x, ScreenPt.y, this);//弹出菜单 2 }
*pResult = 0;
}

3. TreeControl修改节点

参考链接

实现双击修改节点名称,双击时速度需要慢一些,快速双击为展开和折叠节点

  1. 属性设置:将”Edit Labels“改为”True“
  2. 选中Tree控件,在弹出的菜单中选择【类向导】,添加消息函数”TVN_BEGINLABELEDIT“ 和 ”TVN_ENDLABELEDIT“
  3. 添加全局变量CString g_sSelectStr
  4. 修改两个消息函数,,如下:
void TreeTest::OnBeginlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR); g_sSelectStr = m_list.GetItemText(m_list.GetSelectedItem());//得到修改前的数据
*pResult = 0;
} void TreeTest::OnEndlabeleditTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>(pNMHDR); CString strName; //修改后的数据
CString rootstr;
m_list.GetEditControl()->GetWindowText(strName);
if (strName.IsEmpty())
{
AfxMessageBox(_T("数据项不能为空,请重新输入"));
return;
}
if (strName.Compare(g_sSelectStr) == 0)//名字未做修改
{
return;
}
//判断是否由重复的名字
HTREEITEM hRoot = m_list.GetRootItem();
HTREEITEM hFind = FindItem(hRoot,strName);
if (hFind == NULL)//如果没有重名,则修改
{
CString strText;
m_list.GetEditControl()->GetWindowText(strText);
m_list.SetItemText(m_list.GetSelectedItem(),strText);
}
*pResult = 0;
}

4. TreeControl查找节点

//根据名称来查找节点
HTREEITEM TreeTest::FindItem(HTREEITEM item,CString strText)
{
HTREEITEM hFind;
if (item == NULL)//修改数据与根数据不同,遍历时使用
{
return NULL;
}
while(item != NULL)
{
if (strText.Compare(m_list.GetItemText(item)) == 0)//名字相同
{
return item;
}
if (m_list.ItemHasChildren(item))//如果有子节点,则继续判断
{
item = m_list.GetChildItem(item);
hFind = FindItem(item,strText);
if (hFind)
{
return hFind;
}
else
{
item = m_list.GetNextSiblingItem(m_list.GetParentItem(item));
}
}
else
{
item = m_list.GetNextSiblingItem(item);
return FindItem(item,strText);
}
}
return item;
}

5. TreeControl折叠展开节点

//折叠所有的树节点
void TreeTest::mFoldTree(HTREEITEM hTreeItem)
{
if(!m_list.ItemHasChildren(hTreeItem))
{
return;
}
HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
while (hNextItem != NULL)
{
ExpandTree(hNextItem);
hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);
}
m_list.Expand(hTreeItem,TVE_COLLAPSE);
} //展开所有的树节点
void TreeTest::ExpandTree(HTREEITEM hTreeItem)
{
if(!m_list.ItemHasChildren(hTreeItem))
{
return;
}
HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
while (hNextItem != NULL)
{
ExpandTree(hNextItem);
hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);
}
HTREEITEM hchild = m_list.GetChildItem(hTreeItem);
CString NodeData,NodeName;
NodeName = m_list.GetItemText(hchild);
if (NodeData.Compare(_T("2")) == 0 )
{
return;
}
m_list.Expand(hTreeItem,TVE_EXPAND);
} //展开单独的树节点
void TreeTest::ExpandTree2(HTREEITEM hTreeItem)
{
if(!m_list.ItemHasChildren(hTreeItem))
{
return;
}
HTREEITEM hNextItem = m_list.GetChildItem(hTreeItem);
while (hNextItem != NULL)
{
ExpandTree(hNextItem);
hNextItem = m_list.GetNextItem(hNextItem, TVGN_NEXT);
}
m_list.Expand(hTreeItem,TVE_EXPAND);
} void TreeTest::OnClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
hTreeItem = m_list.GetSelectedItem();
*pResult = 0;
} //折叠树按钮
void TreeTest::OnBnClickedButton1()
{
HTREEITEM hItem = m_list.GetSelectedItem();
if (hItem == NULL)
{
HTREEITEM hroot = m_list.GetRootItem();
mFoldTree(hroot);
}
else
{
mFoldTree(hItem);
}
} //展开树按钮
void TreeTest::OnBnClickedButton7()
{
HTREEITEM hItem = m_list.GetSelectedItem();
if (hItem == NULL)
{
HTREEITEM hroot = m_list.GetRootItem();
ExpandTree(hroot);
}
else
{
ExpandTree2(hItem);
}
}

6. TreeControl拖动树

参考网址1

参考网址2

参考网址3

参考网址4

创建树的时候,使用继承类TreeControl进行创建。例如:

注意:此方法目前具有一定的局限性,即节点下必须有子节点,才可以完成拖动。后期进行优化

CXtreeCtrl m_list;
HTREEITEM root = m_list.InsertItem(_T("root"));
HTREEITEM parent1 = m_list.InsertItem(_T("1"),root);
m_list.InsertItem(_T("11"),parent1); HTREEITEM parent2 = m_list.InsertItem(_T("2"),root);
m_list.InsertItem(_T("21"),parent2); HTREEITEM parent3 = m_list.InsertItem(_T("3"),root);
m_list.InsertItem(_T("31"),parent3); HTREEITEM parent4 = m_list.InsertItem(_T("4"),root);
m_list.InsertItem(_T("41"),parent4);

7. 继承类TreeControl

XTreeCtrl.cpp

// XtreeCtrl.cpp : implementation file
// #include "stdafx.h"
#include "Drag.h"
#include "XtreeCtrl.h"
#define DRAG_DELAY 60 // CXtreeCtrl IMPLEMENT_DYNAMIC(CXtreeCtrl, CTreeCtrl) CXtreeCtrl::CXtreeCtrl()
{
m_bDragging = FALSE;
//m_hSelectItem = NULL;
m_hItemDragS = NULL;
m_nHoverTimerID = 0;
m_nScrollTimerID = 0;
m_bInsertAbove = FALSE;
m_hItemDragD = NULL; } CXtreeCtrl::~CXtreeCtrl()
{
} BEGIN_MESSAGE_MAP(CXtreeCtrl, CTreeCtrl)
ON_NOTIFY_REFLECT(TVN_BEGINDRAG, &CXtreeCtrl::OnTvnBegindrag)
ON_WM_LBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP() // CXtreeCtrl message handlers void CXtreeCtrl::OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: Add your control notification handler code here *pResult = 0;
if( (GetTickCount() - m_dwDragStart) < DRAG_DELAY )
return; m_hItemDragS = pNMTreeView->itemNew.hItem;
if (!ItemHasChildren(m_hItemDragS)) //子节点不能被拖拽,注释后可以随意拖拽
{
return;
}
m_hItemDragD = NULL;
m_bDragging = true;
m_nScrollTimerID = SetTimer( 2,40,NULL );
}
HTREEITEM CXtreeCtrl::GetDragTarget(HTREEITEM hItem, POINT point, BOOL& bInsertAbove)
{
ASSERT(hItem != NULL);
HTREEITEM hDragTarget;
CRect rectItem;
GetItemRect(hItem, &rectItem, FALSE);
if (point.y < rectItem.CenterPoint().y)
{
hDragTarget = hItem;
bInsertAbove = TRUE;
}
else
{
if (ItemHasChildren(hItem) && (GetItemState(hItem, TVIS_EXPANDED) & TVIS_EXPANDED))
{
hDragTarget = GetChildItem(hItem);
bInsertAbove = TRUE;
}
else
{
hDragTarget = hItem;
bInsertAbove = FALSE;
}
}
ASSERT(hDragTarget != NULL);
return hDragTarget;
} void CXtreeCtrl::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default HTREEITEM hItem;
UINT flags;
if (m_nHoverTimerID > 0)
{
KillTimer(m_nHoverTimerID);
m_nHoverTimerID = 0;
}
if( m_bDragging )
{
m_nHoverTimerID = SetTimer(1, 800, NULL);
m_HoverPoint = point;
//鼠标经过时高亮显示
CImageList::DragShowNolock( false ); //避免鼠标经过时留下难看的痕迹
HTREEITEM m_hNextDragTarget;
BOOL m_bNextInsertAbove;
if( (hItem = HitTest(point,&flags)) != NULL )
{
m_hNextDragTarget = GetDragTarget(hItem, point, m_bNextInsertAbove);
if ((m_hNextDragTarget != m_hItemDragD) || (m_bInsertAbove != m_bNextInsertAbove))
{
SelectDropTarget(m_hNextDragTarget);
m_hItemDragD = m_hNextDragTarget;
m_bInsertAbove = m_bNextInsertAbove;
EnsureVisible(m_hItemDragD);
RedrawWindow();
}
}
if ((GetScrollPos(SB_HORZ) > 0) && (GetScrollLimit(SB_VERT) > 0))
{
Invalidate();
}
}
CTreeCtrl::OnMouseMove(nFlags, point);
}
HTREEITEM CXtreeCtrl::CopyItem(HTREEITEM hItem1, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝条目
{
TV_ITEM tvSrc;
tvSrc.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_STATE;
tvSrc.hItem = hItem1;
if (!GetItem(&tvSrc))
return htiNewParent; tvSrc.hItem = htiNewParent;
SetItem(&tvSrc);
SetItemText(htiNewParent,GetItemText(hItem1));
SetCheck(htiNewParent,GetCheck (hItem1)); if (tvSrc.state & TVIS_EXPANDED)
Expand(htiNewParent,TVE_EXPAND);
}
HTREEITEM CXtreeCtrl::CopyBranch(HTREEITEM htiBranch, HTREEITEM htiNewParent, HTREEITEM htiAfter) //拷贝分支
{
ASSERT((htiNewParent != NULL) && (htiBranch != NULL));
HTREEITEM hChild;
hChild = GetChildItem( htiBranch );
while ( hChild != NULL )
{
HTREEITEM hChildDest = InsertItem(_T("dest child"), htiNewParent);
CopyBranch( hChild,hChildDest,htiAfter );
CopyItem(hChild,hChildDest,htiAfter);
hChild = GetNextSiblingItem( hChild );
}
return htiNewParent;
} HTREEITEM CXtreeCtrl::InsertItemAndSubtree(HTREEITEM hParent)
{
if ((m_hItemDragD == NULL) || (m_hItemDragS == NULL))
{
ASSERT(FALSE);
return NULL;
}
HTREEITEM hRoot = GetRootItem();
if (!ItemHasChildren(m_hItemDragD)) //如果注释可以随意拖拽父节点到子节点(自己看效果)
{
return NULL;
} else if (hRoot == m_hItemDragD) //如果注释可以随意拖拽父节点至根节点(自己看效果)
{
return NULL;
}
if (hParent == NULL)
hParent = GetParentItem(m_hItemDragD);
if (hParent == NULL)
hParent = TVI_ROOT; HTREEITEM hInsertAfter; if (m_bInsertAbove)
hInsertAfter = GetPrevSiblingItem(m_hItemDragD);
else
hInsertAfter = m_hItemDragD; if ((hInsertAfter == hParent) || (hInsertAfter == NULL))
hInsertAfter = TVI_FIRST; HTREEITEM hNew = InsertItem(_T("dummy"), hParent, hInsertAfter);
if (hNew == NULL)
return NULL; CopyBranch(m_hItemDragS,hNew,m_hItemDragD);
CopyItem(m_hItemDragS,hNew,m_hItemDragD); return hNew;
} void CXtreeCtrl::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
CTreeCtrl::OnLButtonUp(nFlags, point);
if(m_bDragging)
{
m_bLeftBtnUp = TRUE;
KillTimer(m_nScrollTimerID);
m_nScrollTimerID = 0;
KillTimer(m_nHoverTimerID);
m_nHoverTimerID = 0;
ReleaseCapture();
ShowCursor(true);
m_bDragging = false;
SelectDropTarget(NULL);
if (m_bLeftBtnUp)
{
if (m_hItemDragD != NULL)
m_bGoingOK = TRUE;
HTREEITEM m_hParentNew = m_hItemDragD;
while (m_hParentNew != NULL)
{ if(m_hParentNew == m_hItemDragS)
{
//AfxMessageBox(_T("禁止此操作!"), MB_ICONEXCLAMATION);
m_bGoingOK = FALSE;
break;
}
m_hParentNew = GetParentItem(m_hParentNew);
}
HTREEITEM m_hParent;
if (m_bGoingOK)
{
SetRedraw(FALSE);
m_hParent = GetParentItem(m_hItemDragD);
if (m_hParent == NULL)
m_hParent = TVI_ROOT;
if (m_bGoingOK)
{
// We're finally ready to insert the actual item.
HTREEITEM hNew = InsertItemAndSubtree(m_hParent);
if (hNew != NULL)
{
SelectItem(hNew);
DeleteItem(m_hItemDragS);
}
}
}
// Regardless of what happens, we need to reset the tree.
SetRedraw(TRUE);
Invalidate();
}
else
{
// The User chose to abort the drag
EnsureVisible(m_hItemDragS);
// Refresh the screen to get rid of any remnants of the drag drawing
Invalidate();
} }
CTreeCtrl::OnLButtonUp(nFlags, point);
} void CXtreeCtrl::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if( nIDEvent == m_nHoverTimerID)
{
KillTimer( m_nHoverTimerID);
m_nHoverTimerID = 0;
HTREEITEM trItem = 0;
UINT uFlag = 0;
trItem = HitTest(m_HoverPoint,&uFlag);
if( trItem && m_bDragging)
{
SelectItem(trItem);
//Expand( trItem,TVE_EXPAND );
}
}
else if(nIDEvent == m_nScrollTimerID)
{
m_TimerTicks++;
CPoint pt;
GetCursorPos(&pt);
CRect rect;
GetClientRect(&rect);
ClientToScreen(&rect);
HTREEITEM hItem = GetFirstVisibleItem();
if( pt.y < rect.top +10)
{
int slowscroll = 6 - (rect.top + 10 - pt.y )/20;
if( 0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
{
CImageList::DragShowNolock (false);
SendMessage( WM_VSCROLL,SB_LINEUP);
SelectDropTarget(hItem);
m_hItemDragD = hItem;
CImageList::DragShowNolock (true);
}
}
else if(pt.y > rect.bottom - 10)
{
int slowscroll = 6 - (pt.y - rect.bottom + 10)/20; if( 0 == (m_TimerTicks % ((slowscroll > 0) ? slowscroll : 1)))
{
CImageList::DragShowNolock (false);
SendMessage(WM_VSCROLL,SB_LINEDOWN);
int nCount = GetVisibleCount();
for( int i=0 ; i<nCount-1 ; i++ )
hItem = GetNextVisibleItem( hItem);
if( hItem)
SelectDropTarget(hItem); m_hItemDragD = hItem;
CImageList::DragShowNolock (true);
}
}
}
else
CTreeCtrl::OnTimer(nIDEvent);
} void CXtreeCtrl::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//m_dwDragStart = GetTickCount();
//m_hSelectItem = GetSelectedItem();
//UINT nHitFlags = 0;
//HTREEITEM hClickedItem = HitTest( point, &nHitFlags );
CTreeCtrl::OnLButtonDown(nFlags, point);
}

XTreeCtrl.h

#pragma once

// CXtreeCtrl

class CXtreeCtrl : public CTreeCtrl
{
DECLARE_DYNAMIC(CXtreeCtrl) public:
CXtreeCtrl();
virtual ~CXtreeCtrl(); protected:
DECLARE_MESSAGE_MAP() public:
afx_msg void OnTvnBegindrag(NMHDR *pNMHDR, LRESULT *pResult);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
protected:
DWORD m_dwDragStart;
UINT m_nScrollTimerID;
UINT m_nHoverTimerID;
UINT m_TimerTicks;
POINT m_HoverPoint;
BOOL m_bDragging;
BOOL m_bInsertAbove;
BOOL m_bLeftBtnUp;
BOOL m_bGoingOK;
CImageList* m_pDragImage;
HTREEITEM m_hItemDragS;
HTREEITEM m_hItemDragD;
HTREEITEM m_hSelectItem;
HTREEITEM CopyBranch(HTREEITEM htiBranch,HTREEITEM htiNewParent,HTREEITEM htiAfter);
HTREEITEM CopyItem(HTREEITEM hItem,HTREEITEM htiNewParent,HTREEITEM htiAfter);
HTREEITEM GetDragTarget(HTREEITEM hItem, POINT point, BOOL& bInsertAbove);
HTREEITEM InsertItemAndSubtree(HTREEITEM hParent = NULL);
};

MFC TreeControl简单应用的更多相关文章

  1. MFC时间简单比较方法

    MFC//时间简单比较方法 void CMFCsaveListTofileDlg::OnBnClickedButton6()//时间简单比较方法 { // TODO: 在此添加控件通知处理程序代码 C ...

  2. MFC的简单加法器(二)

    创建对话框主要分两大步,第一,创建对话框资源,主要包括创建新的对话框模板.设置对话框属性和为对话框添加各种控件:第二,生成对话框类,主要包括新建对话框类.添加控件变量和控件的消息处理函数等.鸡啄米在本 ...

  3. MFC使用简单总结(便于以后查阅)

    一.资源 共有三个和资源有关的文件:资源头文件resource.h.资源描述文件resource.rc和存放在res文件夹下的具体的资源如图片等. 资源头文件中全部是宏定义,应用程序需要为每个资源都定 ...

  4. MFC制作简单通讯录程序

    学习c++和MFC一段时间了,苦于没有项目实战,所以自己写了一个简单的简单通讯录程序,以前用c#写简单很多,例程是这本书上的实例,我的第一个winform程序也是从这本书上学的,总结c#写的话更简单, ...

  5. MFC实现简单飞机大战(含游戏声音)

    1 实验内容 本实验主要是实现简单的飞机大战游戏,包含游戏声音.碰撞后爆炸效果,有大小敌机等.所用到的知识点如下: 1.贴图技术 2.飞机类.子弹类实现 3.位图移动 4.碰撞判断,实现爆炸效果 5. ...

  6. MFC之简单计算器

    1.界面 2.变量 combobox的变量类型是CComBoBox类型,三个输入框是double类型: 它的type是Drop List 3.代码 (1).初始化combobox BOOL Ccalc ...

  7. Qt And MFC Mouse Over Tips

    Qt鼠标提示分析说明 关于鼠标停留在控件上面,显示提示内容的方法. 对于Qt来说, Qt的某一个控件类, 如果属于GUI的, 那么这个控件类会有一个setToolTip(QString text)的方 ...

  8. mfc和win32区别

    Win32通常是指sdk编程方法,app没有被封装,开发人员需要自己搭程序框架:mfC则是以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量 (整理 ...

  9. <MFC_1>深入剖析MFC的WinMain和消息机制

    一.开篇引论 熟悉Win32开发的朋友,应该非常了解它的基本组成和流程 1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗 ...

随机推荐

  1. dbGet net trace instant pin

    proc rn { net_name } {puts " "puts "Net name : $net_name : "set name_rule [dbget ...

  2. 「JSOI2015」非诚勿扰

    「JSOI2015」非诚勿扰 传送门 我们首先考虑一名女性选中她列表里第 \(x\) 名男性的概率(假设她列表里共有 \(s\) 名男性): \[ P = p \times (1 - p) ^ {x ...

  3. Presto入门介绍

    (一)背景 MapReduce不能满足大数据快速实时adhoc查询计算的性能要求,Facebook2012年开发,2013年开源 (二)是什么 基于内存的并行计算,Facebook推出的分布式SQL交 ...

  4. wordpress 不用插件添加友情链接

    哎,也不知道为啥,网上说的那个link manager这个插件死活找不到啊, 找了一个类似的,但是不是,这么多的英文看了好几遍才发现不是 然后从大神哪里找到一个好方法 在你用的那个主题的functio ...

  5. linux 命令——screen

    最近遇到一个东西aria2,这个玩意,这个是啥呢?Aria2是一个轻量级Linux下载软件,支持HTTP/HTTPS, FTP, SFTP, BitTorrent和磁力链接(官方版),公司系统插件配套 ...

  6. 洛谷P1734 最大约数和(01背包)

    题目描述 选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大. 输入格式 输入一个正整数S. 输出格式 输出最大的约数之和. 输入输出样例 输入 #1 11 输出 #1 9 说 ...

  7. Java面向对象编程 -6

    数组的基本概念 数组的本质:一组相关变量的集合. 但是需要注意的一点是:在java里面讲数组定义为了引用数据类型,所以数组的使用一定要牵扯到内存分配,那么首先一定要想到使用关键字new来处理 数组的定 ...

  8. firefox插件hostadmin自由切换host

    在Mac下firefox插件hostadmin切换host,遇到的第一个问题就是提示权限不足,解决办法,在终端输入以下命令即可: sudo chmod og+w /etc/hosts chmod修改权 ...

  9. 总结 jion,group join 基于方法的查询与查询表达式 对比

    数据源: 代码: using (tempdbEntities context = new tempdbEntities()) { #region 基于方法的查询 Console.WriteLine(& ...

  10. powerbuilder连接oracle数据库

    一.打开已经安装好的pb9.0,主界面菜单栏有个两个圆柱形就行数据库连接,点击database. 二.选择oracle版本,由于数据库版本是9i,可以使用084 oracle8/8i.右键--选择ne ...