lpa编程
package demo;
/**
* 银行
*/
public class Bank {
//存入账户,也就是共享数据,其实应更复杂,比如一家银行有n个储户,或者一个用户有n个银行账户...
private Account account = new Account();
/**
* 这里安全,否则显示账户余额可能出现问题
* @param mony
*/
public synchronized void putMony(int pid, int timeIndex, double money){
account.inMoney(money);
display(pid, timeIndex);
}
private void display(int pid, int timeIndex){
System.out.println("#pid:"+timeIndex+":"+account.getTotal());
}
public static void main(String[] args) {
Bank bank = new Bank();
Person person1 = new Person(bank, 1, 3, 3000);
Person person2 = new Person(bank, 2, 3, 3000);
person1.start();
person2.start();
}
}
/**
* 储户
*/
class Person extends Thread{
private Bank bank;//银行
private int times;//交易次数
private double money;//每次交易金额
private int pid;//用户ID
public Person(Bank bank, int pid, int times, double money) {
this.bank = bank;
this.pid = pid;
this.times = times;
this.money = money;
}
public void run() {
for(int i = 0; i < times; i++){
bank.putMony(pid, i, money);
}
}
}
/**
* 账户
*/
class Account {
//总额
private double total;
public Account() {
//开户后,账户余额设为0
this.total = 0;
}
public double getTotal() {
return total;
}
/**
* 存钱
* @param money
*/
public void inMoney(double money) {
this.total += money;
}
/**
* 取钱(自行处理不能透支的情况...)
* @param money
*/
public void outMoney(double money) {
this.total -= money;
}
}
自己仔细分析下吧
㈡ c语言,编写程序,通过指针操作,比较两个有序数组中的元素,输出两个数组中第一个相同的元素值
c语言指针2个数组查询比较代码如下:
#include<stdio>
intmain()
{
int*lpa,*lpb;
inta[100],b[100],alen,blen,i,j;
printf("输入数组a长度: ");
scanf("%d",&alen);
printf("输入%d个有序数据给数组a ",alen);
for(i=0;i<alen;i++)scanf("%d",&a[i]);
printf("输入数组b长度: ");
scanf("%d",&blen);
printf("输入%d个有序数据给数组a ",alen);
for(i=0;i<alen;i++)scanf("%d",&a[i]);
//查询比较
lpa=a;
for(i=0;i<alen;i++)
{
lpb=b;
for(j=0;j<blen;j++)
{
if(*lpb==*lpa)break;
lpb++;
}
if(*lpb==*lpa)break;
lpa++;
}
if(*lpb==*lpa)
{
printf("两数组中发现第一个相同元素:%d",*lpa);
}
else
{
printf("两数组中没有发现相同元素");
}
}
㈢ 谁知道多线程编程
主要内容:
1, 工作者线程
2, 用户界面线程
3, 同步
线程被分为工作者线程和用户用户界面线程。用户界面的线程的特点是拥有单独的消息队列,可以具有自己的窗口界面,能够对用户输入和事件作出反应。
可以用以下方法建立一个工作者线程。
UINT MyThreadProc(LPVOID pParam)
{
…
}
AfxBeginThread(MyThread,..);
它有六个参数,第一个为控制函数,第二个为启动线程时传给控制函数的入口参数,当前线程的优先级,当前线程的栈的大小,当前线程的创建状态,安全属性,后四个有默认值。
用户界面线程:
首先利用应用程序向导建立单文档程序Thread,再建立Thread1 : public CWinThread,
Frame1 : public CFrameWnd,可以用Ctrl+w建立这两个新类。
在CThreadApp中加一个指针Thread1* pThread1,在BOOL CThreadApp::InitInstance()
中进行初始化:
pThread1 = new Thread1();
pThread1->CreateThread();
将Thread1的构造函数改成公有。
在Thread1中加一个指针Frame1* m_pWnd,然后初始化。
BOOL Thread1::InitInstance()
{
m_pWnd = new Frame1();
return TRUE;
}
把Frame1的构造函数改成公有,在Thread.h中包含#include "Frame1.h"。
在资源编辑器中编辑一个菜单IDR_MENU,它有一个菜单项ID_BEGIN。
Frame1::Frame1()
{
Create(NULL,"Demo");
ShowWindow(SW_SHOW);
UpdateWindow();
CMenu menu;//可以用局部变量,因为以后不会用到它了,加菜单。
menu.LoadMenu(IDR_MENU);
SetMenu(&menu);
}
同步
多线程的一个难点是各线程间的协调。同样的方法在CThreadApp中再开一个线程。
BOOL CThreadApp::InitInstance()
{
。。。。。。
pThread1 = new Thread1();
pThread1->CreateThread();
pThread2 = new Thread1();
pThread2->CreateThread();
。。。。。。
}
为IDR_MENU中的菜单在Frame1中设立响应函数,方法也是Ctrl+w打开类向导。并在Frame1中定义一个全局整形变量n,初始值为0.
HANDLE handle=CreateSemaphore(NULL,0,1,"he");
WaitForSingleObject(handle,10000);
CString str;
n++;
str.Format("第%d次工作",n);
MessageBox(str);
ReleaseSemaphore(handle,1,NULL);
当你点击Frame1的菜单时,会弹出一个对话框,暂时不要点 确定,点击另一个线程的菜单,暂不会弹出对话框,确定刚才的对话框,另一个线程的对话框也弹出来了。
这个同步的方法称为信号量。它允许有限的线程存取某个共享的系统资源,采用计数器来实现信号量。
HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpa,LONG cSemInitial,LONG cSemMax,LPTSR lpszSemName);
第一个参数来指明所创建的对象是否可以被其子进程继承。如果你希望在所有的子进程之间共享这个信号量,可以把它的成员bInheritHandle设为true,也可以直接设为NULL来使用默认的安全设置第二个参数是还可以让几个线程使用,第三个参数是最多可以让几个线程使用。
最后参数是信号量的名字,在其它的进程中调用CreateSemapphore()或OpenSemaphore()时使用这个字符串作为参数之一就可以得到信号量的句柄。
ReleaseSemaphore(HANDLE hSemaphore, LONG cRelease,LPLONG plPrev)
㈣ 基于遗传算法路径优化C++编程
[cpp]
bool CAStar::Search(int X, int Y, std::list<POINT> &lResult, double dbGapBreak)
{
if(X < 0 || Y < 0
|| X > m_dwMapWidth || Y > m_dwMapWidth ||
m_dwDestinationX < 0 || m_dwDestinationX < 0 ||
m_dwDestinationX > m_dwMapWidth || m_dwDestinationY > m_dwMapHeight)
{
//_outf("坐标或地图参数错误!");
return false;
}
LPAPOINT p = new APOINT;
p->x = X;
p->y = Y;
p->parent = NULL;
p->dbGap = _p2g(X, Y, m_dwDestinationX, m_dwDestinationY);
m_lOpen.push_front(p);//起始节点加入到开启列表
m_lSafe.push_back(p);//加入到公共容器,任何新分配的节点,都要加入到这里,便于算法执行完后清理
std::list<LPAPOINT>::iterator it;
DWORD dwTime = clock();
while(!m_lOpen.empty())
{
//这里就是反复遍历开启列表选择距离最小的节点
it = GetMingapNode();
if((*it)->dbGap <= dbGapBreak)
break;
p = *it;
GenerateSuccessors(it);
}
if(!m_lOpen.empty())
{
//如果列表不为空,从最后一个节点开始拷贝路径到返回值中
//_outf("最终寻路到:%X, %X", p->x, p->y);
POINT point;
while(p)
{
point.x = p->x;
point.y = p->y;
lResult.push_front(point);
p = p->parent;
}
}
for(it = m_lSafe.begin(); it != m_lSafe.end(); ++it)
{
//清理内存
if(*it != NULL)
{
m_pMap[(*it)->y][(*it)->x] = 1;//会被添加到m_lSafe的节点,一定是最初为1的节点,所以可以在这里恢复地图数据
delete (*it);
*it = NULL;
}
}
m_lSafe.clear();//清空容器
//_outf("耗时:%d 毫秒", clock() - dwTime);
if(m_lOpen.empty())
{
//_outf("寻路失败");
return false;
}
m_lOpen.clear();//清空开启列表
//_outf("寻路成功,节点数:%d", lResult.size());
return true;
}
bool CAStar::Search(int X, int Y, std::list<POINT> &lResult, double dbGapBreak)
{
if(X < 0 || Y < 0
|| X > m_dwMapWidth || Y > m_dwMapWidth ||
m_dwDestinationX < 0 || m_dwDestinationX < 0 ||
m_dwDestinationX > m_dwMapWidth || m_dwDestinationY > m_dwMapHeight)
{
//_outf("坐标或地图参数错误!");
return false;
}
LPAPOINT p = new APOINT;
p->x = X;
p->y = Y;
p->parent = NULL;
p->dbGap = _p2g(X, Y, m_dwDestinationX, m_dwDestinationY);
m_lOpen.push_front(p);//起始节点加入到开启列表
m_lSafe.push_back(p);//加入到公共容器,任何新分配的节点,都要加入到这里,便于算法执行完后清理
std::list<LPAPOINT>::iterator it;
DWORD dwTime = clock();
while(!m_lOpen.empty())
{
//这里就是反复遍历开启列表选择距离最小的节点
it = GetMingapNode();
if((*it)->dbGap <= dbGapBreak)
break;
p = *it;
GenerateSuccessors(it);
}
if(!m_lOpen.empty())
{
//如果列表不为空,从最后一个节点开始拷贝路径到返回值中
//_outf("最终寻路到:%X, %X", p->x, p->y);
POINT point;
while(p)
{
point.x = p->x;
point.y = p->y;
lResult.push_front(point);
p = p->parent;
}
}
for(it = m_lSafe.begin(); it != m_lSafe.end(); ++it)
{
//清理内存
if(*it != NULL)
{
m_pMap[(*it)->y][(*it)->x] = 1;//会被添加到m_lSafe的节点,一定是最初为1的节点,所以可以在这里恢复地图数据
delete (*it);
*it = NULL;
}
}
m_lSafe.clear();//清空容器
//_outf("耗时:%d 毫秒", clock() - dwTime);
if(m_lOpen.empty())
{
//_outf("寻路失败");
return false;
}
m_lOpen.clear();//清空开启列表
//_outf("寻路成功,节点数:%d", lResult.size());
return true;
}
新增的SearchEx源代码如下:
nBeginSift 参数为循环初始值,nEndSift为循环结束值,其实就是一个for循环的起始值与结束值。
这个循环的引用计数,最终会被 乘于 10 来作为距离分段选择路径进行路线优化
nBeginSift 与 nEndSift的间距越大,并不表示最终路径就越好,最终优化出来的路径,还是会和地形有关。
其实最好路径优化算法是按照角度的变化来选择路径优化,但是预计开销会比较大,有了这个优化方式作为基础,你可以自己去写根据角度变化来优化的算法。
[cpp]
bool CAStar::SearchEx(int X, int Y, std::list<POINT> &lResult, double dbGapBreak, int nBeginSift, int nEndSift)
{
DWORD dwTime = clock();
if(!Search(X, Y, lResult, dbGapBreak))
return false;
std::list<POINT>::iterator it = lResult.begin();
std::list<POINT>::iterator it2 = it;
std::list<POINT> l2;
for(int i = nBeginSift; i < nEndSift; i++)
{
it = lResult.begin();
it2 = it;
for(;it != lResult.end(); ++it)
{
if(_p2g(it2->x, it2->y, it->x, it->y) > (double)(i * 10))
{
SetDestinationPos(it->x, it->y);
l2.clear();
if(Search(it2->x, it2->y, l2, 0.0))
{
it = lResult.erase(it2, it);
lResult.insert(it, (l2.begin()), (l2.end()));
}
it2 = it;
}
}
}
_outf("耗时:%d 毫秒", clock() - dwTime);
return true;
}
bool CAStar::SearchEx(int X, int Y, std::list<POINT> &lResult, double dbGapBreak, int nBeginSift, int nEndSift)
{
DWORD dwTime = clock();
if(!Search(X, Y, lResult, dbGapBreak))
return false;
std::list<POINT>::iterator it = lResult.begin();
std::list<POINT>::iterator it2 = it;
std::list<POINT> l2;
for(int i = nBeginSift; i < nEndSift; i++)
{
it = lResult.begin();
it2 = it;
for(;it != lResult.end(); ++it)
{
if(_p2g(it2->x, it2->y, it->x, it->y) > (double)(i * 10))
{
SetDestinationPos(it->x, it->y);
l2.clear();
if(Search(it2->x, it2->y, l2, 0.0))
{
it = lResult.erase(it2, it);
lResult.insert(it, (l2.begin()), (l2.end()));
}
it2 = it;
}
}
}
_outf("耗时:%d 毫秒", clock() - dwTime);
return true;
}