关于244128133

Unity3D游戏程序员

Unity3D 5.0 刚体API更改

刚才做项目时发现一个问题,在Unity5.0 以后的版本中 不可以直接对物体引用刚体的API如

hit.rigidbody.AddForce此用法在5.0以后已经不可以使用了而取而代之的是 使用

hit.GetComponent<Rigidbody>().AddForce来代替它.

相同的其他刚体API也是这样的,如发现其他函数的调用有问题也可以试试先获取组件再调用哦.

 

反转单向链表

   
 网上有许多代码 看了一下发现他们的好多反转后都缺失了头结点.
 所以自己又写了一个.

//
#include "stdafx.h"
#include "iostream"
using namespace std;
struct ListNode
{
ListNode* next;
int data;
	ListNode()
	{
	next=NULL;
	data=0;
 
	}
};
 
ListNode *ReverseList(ListNode *&list)
{
	ListNode *head = list, *last = NULL;
	list = list->next;
 	while (list){
		head->next = last;
		last = head;
		head = list;
		list = list->next;
	}
	head->next = last;
	return head;
}




//创建链表添加结点;
void CreateNode(ListNode*&head, int data)
{
	ListNode *fist = head;
	while (head != NULL)
	{
		if (head->next == NULL)
		{
			ListNode *tem = new ListNode();
			tem->data = data;
			head->next = tem;
			break;
		}
		head = head->next;
	}
	head = fist;
}
int main(int argc, char* argv[])
{
ListNode *head=new ListNode();
CreateNode(head,1);
CreateNode(head,2);
CreateNode(head,3);
CreateNode(head,4);
CreateNode(head,5);
CreateNode(head,6);
CreateNode(head,7);
ListNode *tem=head;

while (head!=NULL)
{
cout<<head->data<<endl;
head=head->next;
}
ListNode* re=ReverseList(tem);
cout<<"反转链表:"<<endl;
while (re!=NULL)
{
cout<<re->data<<endl;
re=re->next;
}
getchar();
return 0;
}

翻转句子中单词的顺序

     题目描述:翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。
     为简单起见,标点符号和普通字母一样处理。如:"I am a student."翻转成"student. a am I"。
             在上述题目中我看到网上好多答案在最后一个单词是没有经过翻转的,假如句子翻转后最后
     一个单词不是一个字母(也就是原句中的第一个单词不是一个字母),那么就会出现最后一个单词没有翻转的     情况.所以在最后还要进行一次单词翻转.
     如: “My name is fgreen”翻转后应该是”fgreen is name My”
    代码如下:
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
using namespace std;
void ReverseWord(char *str,int start,int end)
{
	char tem=' ';
	while (start<end)
	{
		 tem=str[start];	
		 str[start]=str[end];
		 str[end]=tem;
		 ++start;
		 --end;
	}
}
void ReverseSentence(char *str)
{ 
	if(str==NULL||*str=='\0')
		return;
	ReverseWord(str,0,strlen(str)-1);
	int i=0;
	int t=i;
	while (true)
	{
         if(str[i]==' ')
		 {   
			 ReverseWord(str,t,i-1); 
			 t=i+1;		
		 }
        ++i;
		if(str[i]=='\0')//最后一个单词也要翻转;
        { ReverseWord(str,t,i-1); 
		  break;
		}
	}
}
int main(int argc, char* argv[])
{
	char str[]="My name is fgreen";
	ReverseSentence(str);
	cout<<str<<endl;
	getchar();
	return 0;
}

 

为什么在16位机器中有符号整形的范围是-32768-32767?

        如果以最高位为符号位,二进制原码最大为0111  1111  1111  1111 =  215 – 1 =32767

                                             最小为1111  1111  1111  1111 =-215 – 1=-32767

此时0有两种表示方法,即正0和负0:0000  0000  0000  0000 = 1000  0000  0000  0000 = 0

所以,二进制原码表示时,范围是-32767~-0和0~32767,因为有两个零的存在,所以不同的数值个数一共只有2的16次方减1个,比16位二进制能够提供的2的16次方个编码少1个。

但是计算机中采用二进制补码存储数据,即正数编码不变,从0000  0000  0000  0000到0111  1111  1111  1111依旧表示0到32767,而负数需要把除符号位以后的部分取反加1,即-32767的补码为1000  0000  0000  0001。

到此,再来看原码的正0和负0:0000000000000000和1000000000000000,补码表示中,前者的补码还是0000000000000000,后者经过非符号位取反加1后,同样变成了0000  0000  0000  0000,也就是正0和负0在补码系统中的编码是一样的。但是,我们知道,16位二进制数可以表示2的16次方个编码,而在补码中零的编码只有一个,也就是补码中会比原码多一个编码出来,这个编码就是1000000000000000,因为任何一个原码都不可能在转成补码时变成1000  0000  0000  0000。所以,人为规定1000  0000  0000  0000这个补码编码为-32768。

所以,补码系统中,范围是-32768 – 32767。

因此,实际上,二进制的最小数确实是1111111111111111,只是二进制补码的最小值才是1000000000000000,而补码的1111111111111111是二进制值的-1。

重点是:

1.负数在计算机中是补码表示的!

2.正0和负0在计算机里面表示重叠了

3.人为规定负数里面1000 0000 0000 0000是负数里面最小的,-32768就是它。

不使用递归实现斐波那契数列

由于递归的写法效率太过低下,要求用非递归实现。

 

定义斐波那契数列如下:
{ 0                        n=0
{ 1                        n=1
{ f(n-1)+f(n-2)    n>1

// ConsoleApplication4.cpp : 定义控制台应用程序的入口点。
int fbnqsl(int n)
{
int tem = 0, h1 = 0, h2 = 1;
if (n < 0)
return -1;
if (1 == n || 0 == n)
return n;
for (int i = 2; i < n; ++i)
{
tem = h2;
h2 += h1;
h1 = tem;
}
return h1 + h2;
}
int main(int argc, char* argv[])
{
cout << fbnqsl(10);
getchar();
return 0;
}

 

第一个只出现一次的字符

在一个字符串中找到第一个只出现一次的字符。如输入aabbccddvllllsd,则输出v。听说此题目为2006年谷歌笔试.

C++代码如下:

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
using namespace std;

char FindFirstShow(char *data)
{
	int s[256]={0};
	char *str=data;
	while(*str!='\0')
	{   
        ++s[*str];
		++str;
	}
  for(char* i=data;*i!='\0';++i)
	  if(s[*i]==1)
	  {
		  return *i;
	  }
	  return NULL;	
}
int main(int argc, char* argv[])
{
	char *str="aabbccddvllllsd";
	cout<<"第一个不重复的字符是"<<FindFirstShow(str)<<endl;
	getchar();
	return 0;
}

 

 

在一个有序数组中查找2个数和为SUM的个数

输入一个递增排序的数组和一个数字sum,在数组中查找两个数,使得它们的和正好是s。
如果有多对数字的和等于sum,输出有多少对数满足。

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
using namespace std;
//查找函数;
int  FindSum(int *arr,int length,int sum)
{
	int *end=arr+length-1,*start=arr,number=0;

	while (start!=end)
	{  
		if(*start+*end<sum)
		   ++start;
		else if(*start+*end>sum)
			--end;
		else
		{  
			 ++number;
			 --end;//这里写++start也可以
		}
	}
	return number;
}
int main(int argc, char* argv[])
{

	int a[]={1,2,3,4,5};//测试数组
	cout<<"数组中和为7的有"<<FindSum(a,5,7)<<"对"<<endl;
	getchar();
	return 0;
}

链表中倒数第k个结点

输入一个链表,输出该链表的倒数第k个结点。设尾结点为倒数第1个结点,例如一个链表

从头到尾结点的值依次为1、2、3、4、5、6,则倒数第三个结点为4。

// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "iostream"
using namespace std;
struct ListNode
{
ListNode* next;
int data;
ListNode()
{
next=NULL;
data=0;

}
};

//找到链表倒数第K个点;
ListNode *FindLastNode(ListNode*head,int k)
{
if(head==NULL||k<1)
return NULL;
ListNode* ret=head;
for(int i=1;i!=k;++i)
{
if(head->next!=NULL)
head=head->next;
else
return NULL;

}
while (head->next!=NULL)
{
head=head->next;
ret=ret->next;
}
return ret;
}

//创建链表添加结点;
ListNode *CreateNode(ListNode* head,int data)
{
ListNode *fist=head;

while (head!=NULL)
{
if(head->next==NULL)
{
ListNode *tem=new ListNode();
tem->data=data;
head->next=tem;
break;
}
head=head->next;
}
return fist;
}
int main(int argc, char* argv[])
{
ListNode *head=new ListNode();
head=CreateNode(head,1);
head=CreateNode(head,2);
head=CreateNode(head,3);
head=CreateNode(head,4);
head=CreateNode(head,5);
head=CreateNode(head,6);
head=CreateNode(head,7);
ListNode *tem=head;
while (head!=NULL)
{
cout<<head->data<<endl;
head=head->next;
}
int k=4;
cout<<"倒数第"<<k<<"个是:"<<FindLastNode(tem,k)->data<<endl;
getchar();
return 0;
}

 

博客版本更新

发现自己的博客版本太老了,不能进行屏幕自适应.所以今天就更新了一下.后来发现我的Wordpress是SAE版的,不能自动升级了.  只能自己手动上传了.另外也装了许多新的插件,手机浏览也很合适了 哈哈.

先测试一下虾米音乐插件吧.

[hermit auto=”0″ loop=”0″ unexpand=”0″ fullheight=”0″]netease_songs#:399366062,26609796[/hermit]

 

 

 

A*寻路算法C++实现

 写了一天终于用C++的方式把 A*算法撸出来了,写完后才发现如果有拐角的地方有4种方式需要不同的处理他.

  起点和到达点的位置关系和对角的方向关系的不同所以判断的条件也不同了.暂时没有找到更好的方法,如果有谁知道可以联系我.算法实现原理:http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html代码如下:

</pre>

#include "stdafx.h"
#include "iostream"
#include <list>
#include <cstdlib>
#include <string>
#define STEP 10
#define ANGLE 14
#define ROW 10
#define COL 10
using namespace std;

struct Point
{

Point(int x,int y)
 {
 X=x;
 Y=y;
 F=0;
 G=0;
 H=0;
 parent=NULL;
 }
 Point()
 {

}
 void CalcF()
 {
 F=G+H;
 }

bool operator<(Point p2)
 {
 if (F<p2.F)
 return true;
 return false;
 }

Point *parent;
 int F;
 int G;
 int H;
 int X;
 int Y;
};

class CFindPath
{
public:
 CFindPath();
 CFindPath(int map[][COL]);
 ~CFindPath();
 Point *GetPath(Point start,Point end,bool isAagle);//获取路径链表;
 list<Point> GetSurroundPoint(Point &,bool);//获取周围可到达的点;
 bool IsCanReach(int x,int y);//判断是否是墙壁;
 void ChangePoint(Point start,Point point);//改变已在开启列表的点;
 void AddPoint(Point start,Point end,Point point);//添加不在开启列表的点;
 int CalculateG(Point,Point );//计算G
 int CalculateH(Point end,Point point);//计算H
 bool IsCanReach(Point start,int x,int y,bool isAngle);//判断是否可到达;
 Point *FindOpenListPoint(Point p);
 Point *FindColseListPoint(Point p);
 Point *FPoint(Point p);
private:
 list<Point> openList;//开启列表;
 list<Point> colseList;//关闭列表;
 list<Point> temList;
 int points[ROW][COL];
};

CFindPath::CFindPath()
{

}
CFindPath::CFindPath(int map[][COL])
{
 for(int i=0;i<ROW;i++)
 for(int j=0;j<COL;j++)
 points[i][j]=map[i][j];
}
CFindPath::~CFindPath()
{
 delete points;
}

&nbsp;

Point* CFindPath::GetPath(Point start,Point end,bool isAngle)//核心算法A*路径查找,isAngle表示是否可以越过拐角;
{
 openList.push_back(start);
 while (!openList.empty())
 {
 openList.sort();//根据F值由小到大排序;
 Point temp=openList.front();//取出F值最小的;
 colseList.push_back(temp);//加入到关闭列表;
 openList.pop_front();//开启列表中删除F值最小的;
 list<Point> surroundPoints=GetSurroundPoint(temp,isAngle);//取出周围可到达的点;
 while (!surroundPoints.empty())//对每个可到达的周围的点进行判断;
 {
 Point point=surroundPoints.front();
 if(FindOpenListPoint(point))//若开启列表中存在这个点;
 ChangePoint(temp,point);//判断是否是最优路径如果是改变父结点若不是则什么也不做;
 else
 AddPoint(temp,end,point);//若不在开启列表则加入;
 surroundPoints.pop_front();
 }
 if(FindOpenListPoint(end))
 return FindOpenListPoint(end);
 }
 return FindOpenListPoint(end);
}

&nbsp;

void CFindPath::ChangePoint(Point start,Point point)//改变点的父结点重新计算F值;
 {

 int G=CalculateG(start,point);
 if(G<point.G)
 { point.parent=new Point(start);
 point.G=G;
 point.CalcF();
 }
 }

void CFindPath::AddPoint(Point start,Point end,Point point)//添加点到开启列表;
 {
 point.parent=new Point(start);
 point.G=CalculateG(start,point);
 point.H=CalculateH(end,point);
 point.CalcF();
 openList.push_back(point);
 }

int CFindPath::CalculateG(Point start,Point point)//计算G值
 {

 int parentG=0;
 int G=(abs(point.X-start.X)+abs(point.Y-start.Y))!=2?STEP:ANGLE;
 if(point.parent)
 parentG=point.parent->G!=0?point.parent->G:0;
 return G+parentG;

}

int CFindPath::CalculateH(Point end,Point point)//计算H值;
 {
 int step=abs(point.X-end.X)+abs(point.Y-end.Y);
 return step*STEP;

}

Point* CFindPath::FindOpenListPoint(Point p)//查找点是否在开启列表中;
 {
 list<Point>::iterator i;
 for(i=openList.begin();i!=openList.end();i++)
 {
 if(p.X==i->X&&p.Y==i->Y)
 {
 return &*i;
 }
 }
 return NULL;
 }

list<Point> CFindPath::GetSurroundPoint(Point &p,bool isAngle)//获取周围可到达结点;
{ list<Point> temPoints;

for(int i=p.X-1;i<=(p.X+1>=ROW?p.X:p.X+1);i++)
 for(int j=p.Y-1;j<=(p.Y+1>=COL?p.Y:p.Y+1);j++)
 {
 if(IsCanReach(p,i,j,isAngle))
 {

 Point mPoint(i,j);
 temPoints.push_back(mPoint);
 }
 }
 return temPoints;
}
 Point *CFindPath::FindColseListPoint(Point p)
 {

list<Point>::iterator i;
 for(i=colseList.begin();i!=colseList.end();i++)
 {
 if(p.X==i->X&&p.Y==i->Y)
 {
 return &*i;
 }
 }
 return NULL;
 }

bool CFindPath::IsCanReach(Point start,int x,int y,bool isAngle)//判断点是否可以到达
{
 Point point;
 point.X=x;
 point.Y=y;
 if(!IsCanReach(x,y)||FindColseListPoint(point))
 {
 return false;
 }
 else
 {
 if(abs(x-start.X)+abs(y-start.Y)==1)
 return true;
 else
 {
 if(isAngle)//如果可以拐角直接返回
 return isAngle;

//以下为4种不同拐角的情况判断
 if(x<start.X&&y<start.Y) //(到点) 0 | 1 //到点和起点的位置有4种情况所以有4种不同的拐角
 { // -----|-----
 if(points[start.X][y]==0&&points[x][start.Y]==0) // 1 | 0(起点)
 return true; //
 }
 else if(x<start.X&&y>start.Y)
 {
 if(points[x][start.Y]==0&&points[start.X][y]==0)
 return true;
 }
 else if(x>start.X&&y<start.Y)
 {
 if(points[start.X][y]==0&&points[x][start.Y]==0)
 return true;
 }
 else if(x>start.X&&y>start.Y)
 {
 if(points[x][start.Y]==0&&points[start.X][y]==0)
 return true;

}
 return false;

 }
 }
}

bool CFindPath::IsCanReach(int x,int y)//判断点是否可以通过
{
 return points[x][y]==0;
}
int main(int argc, char* argv[])
{
 int map[10][10]={//地图//0 1 2 3 4 5 6 7 8 9
 /*0*/{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
 /*1*/{ 1, 0, 0, 1, 1, 0, 1, 0, 0, 0},
 /*2*/{ 1, 0, 1, 1, 1, 0, 0, 0, 0, 0},
 /*3*/{ 1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
 /*4*/{ 1, 1, 1, 1, 0, 0, 0, 0, 1, 1},
 /*5*/{ 1, 1, 0, 1, 0, 0, 0, 0, 0, 0},
 /*6*/{ 1, 0, 0, 0, 0, 0, 0, 1, 0, 0},
 /*7*/{ 1, 1, 0, 0, 1, 1, 0, 0, 0, 1},
 /*8*/{ 1, 1, 0, 0, 1, 0, 0, 1, 0, 1},
 /*9*/{ 1, 1, 1, 0, 1, 1, 1, 1, 0, 1}
 };
 CFindPath path(map);//初始化地图;
 Point start(1,1);//起点;
 Point end(9,8);//终点
 Point *point=new Point();
 point=path.GetPath(start,end,false);
 if(point==NULL)
 {
 cout<<"无法到达终点!"<<endl;
 }
 else
 {
 while (point!=NULL)
 {
 cout<<point->X<<","<<point->Y<<endl;
 point=point->parent;
 }
 }
 delete point;
 point=NULL;
 getchar();
 return 0;
}

&nbsp;
<pre>

以上代码在VS2012上测试通过.