c++栈的出栈和入栈操作
这里写栈用结构体表示,栈底和栈顶的类型是node类型
二叉搜索树(二叉排序树)的特性:左子树所有值小于节点,右子数所有值都大于节点。
如果二叉搜索树存放的是字母ABCDEFG,那么D节点左边的应该是ABC,D节点右边的是EFG
在写strcpy等函数的时候会报_CRT_SECURE_NO_WARNINGS错误,解决方法,在头文件stdafx.h里(注意:一定要在没有include任何头文件之前)加上
#define _CRT_SECURE_NO_DEPRECATE
static_cast和dynamic_cast:
是C++的类型转换操作符。编译器隐式执行的任何类型转换都可以由static_cast显式完成,即父类和子类之间也可以利用static_cast进行转换。而dynamic_cast只能用于类之间的转换。那么dynamic_cast的存在还有什么意义呢?因为dynamic_cast提供了一个重要的特性:运行时类型检查来保证转换的安全性。
符号优先级:
括号成员第一; 括号运算符[]() 成员运算符. ->
全体单目第二; 所有的单目运算符比如++ -- +(正) -(负) 指针运算*&
乘除余三,加减四; 这个"余"是指取余运算即%
移位五,关系六; 移位运算符:<< >> ,关系:> < >= <= 等
等于(与)不等排第七; 即== !=
位与异或和位或; 这几个都是位运算: 位与(&)异或(^)位或(|)
"三分天下"八九十;
逻辑或跟与; 逻辑运算符:|| 和 &&
十二和十一; 注意顺序:优先级(||) 底于 优先级(&&)
条件高于赋值, 三目运算符优先级排到 13 位只比赋值运算符和","高
逗号运算级最低! 逗号运算符优先级最低
把一个10进制数,转成5进制代码:
思路:由于第一位为5的一次方,第二位为5的二次方,第三位为5的三次方。。。明显是个递归,或迭代 ,目标数为int target
while(target){
}
其次要非常注意的是要一步一步来,可以设target为2,那么直接得到2%5=2;就等于2,因此想到两行代码
int a=target%5;
target=a;
再设target为12,那么12%5=2; 12/5=2;因此又得到一行代码
int a=target%5;
target=a;
int b=target/5;
又因为第一个2为个位,第二个2位十位,所以target=2+2*10;那么如果是百位,2*100千位2*1000,增加一位乘以10因此还要设一个n,要n*=10;因此代码为
int a=target%5;
target=target+n*a;
n*=10;
int b=target/5;
最后代码为
int n=1;
while(b){
int a=target%5;
target=target+n*a;
n*=10;
int b=target/5;
}切记,遇到递归或者迭代,不容易一下写出来,要先用个特别小的数来测试,写一点,在增加一点来测试,再写一点,不能通过一个很大的数来测试,那么会懵逼的。
这题给我的启示,别老想着开宝马,先把自行车老老实实骑好了再说!
我自己一直感觉自己属于看东西偏向整体的人,对于一个很大的东西优秀的程序员要能够很细心的拆分出来,可是自己总是属于看到一个很大的东西会有些懵,有时候会不知道如何下手,在考场上5的n次幂明显用while循环里面n*=5;就可以得到,但是自己还是会犯懵。。
比如厦门极致二面问的这个问题自己就挂了,一个10*10网格,连接任意两个方格的中点,遍历出直接经过的所有方格,说出思路即可,会的人因为做过所以一下就往那个思路上想了,可是没做过的人可能会有点懵,一个看上去宏大的东西要学会拆分,一步一步得到细小的结果来逼近最终结果。另外有些条件很隐晦,需要自己加上。
对于很大的图,放大画出一个放大图容易看出。可以看到AB连线先和x=2相交,经过的格子是该点左右两个,然后和y=2相交,经过该点的上下两个格子。同理又和x=3相交。经过该点的左右两个格子,只要是和x轴相交,那么是经过左右格子,和y轴相交经过,上下两个格子,比如A=(1.5,1.5) B=(5.5,5.5)那么AB两线分别和x=2,x=3.x=4.x=5做交点,取得所有左右格子,分别和y=2,y=3,y=4 做交点,取得所有上下格子,放到数组中,去重即可
自己一直以为找工作就像谈恋爱。需要有勇气去通过笔试面试暴露自己的缺点,才能发现自己的不足之处。好好反思,不断进步,才能在不断磨砺中变得完美,昨天畅唐宣讲会,HR在台上大谈公司待遇,好的公司福利就是好啊,我在最后一排留着哈喇子望梅止渴。自己多想去该公司。可是笔试就一个10进制转5进制的c语言代码自己都懵了半天。
如果自己可以拿没事,反正自己也不想离开成都这个理由来安慰自己,那么还要错过多少好的机会?(附上畅唐的待遇和发言拿了个毛绒玩具)
所以说,骚年,好好努力吧,多努力一点看到的东西和遇到的机会真的不一样,很多时候我们会迷茫,迷茫就会寻求诱惑,追求刺激来寻求成就感。直到看到那么诱人的机会跟自己擦肩而过才后悔莫及,当初的颓废和堕落是多么的幼稚!同样的道理,许多时候我们会被生活工作的平淡停止脚步,直到我们看到梦想那么美是才会追悔,
我们很容易被一个专注的人所吸引,小时候看成龙电影,长大看dopa直播,那些都是他们长期专注于某个领域的结晶,每次看dopa直播都很喜欢他细腻的操作,如果说长期的专注上升为一种艺术从而能获得源源不断的成就感而被别人所吸引,那么我们如何通过自己的努力获得自己的成功?如果当初我们即使迷茫过,彷徨过,甚至深受打击也不放弃努力,那么看到的风景是不是会不一样?
笔试题:
[StructLayout(LayoutKind.Sequentia),Pack=4)]
struct st
{
byte b;
string s;
char c;
long d;
}
sizeof(st)=
答案24, sizeof(b)=1; sizeof(s)=4 sizeof(c)=1 sizeof(d)=8 ,为什么程序跑出来是24?
这里pack=4说明是按4字节对齐的,b=4,s=4,c=4,d=8,面试官说是应该是20,我觉得对齐后相加是20,但必须是8的倍数,所以是24
注意的是这个对齐是指,每个元素小于4个字节都是按照4字节对齐的。
备注float为4字节,double为8字节,long为8字节 ,string为4字节
ArrayList和list:底层数据结构使数组结构,查询速度快,增删改慢,
LinkList:底层使用链表结构,增删速度快,查询稍慢;
Vector:底层是数组结构,线程同步ArrayList是线程不同步;
可变长度数组不断new数组:
ArrayList当初始化容量超过10时,会new一个50%的内存 ,把原来的东西放入这150%中;
Vector:当容量超过10时,会new一个100%的浪费内存;
面试官问我map用什么实现的,我是红黑树,他说不对,是哈希表,其实STL里面map使用红黑树,在java里面hashmap使用哈希表实现的
平衡二叉树的作用:
平衡二叉树必定是二叉搜索树,它可以通过红黑树算法来实现查找插入删除数据时间复杂度为logn,大大降低了时间复杂度
友元(友元函数、友元类和友元成员函数) C++
1、友元函数
友元函数是指某些虽然不是类成员函数却能够访问类的所有成员的函数。类授予它的友元特别的访问权,这样该友元函数就能访问到类中的所有成员
#include <iostream>
using namespace std;
class A
{
public:
friend void set_show(int x, A &a); //该函数是友元函数的声明
private:
int data;
};
void set_show(int x, A &a) //友元函数定义,为了访问类A中的成员
{
a.data = x;
cout << a.data << endl;
}
int main(void)
{
class A a;
set_show(1, a);
return 0;
}
2、友元类
友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。
关于友元类的注意事项:
(1) 友元关系不能被继承。
(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。
(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明。
#include <iostream>
using namespace std;
class A
{
public:
friend class C; //这是友元类的声明
private:
int data;
};
class C //友元类定义,为了访问类A中的成员
{
public:
void set_show(int x, A &a) { a.data = x; cout<<a.data<<endl;}
};
int main(void)
{
class A a;
class C c;
c.set_show(1, a);
return 0;
}
3、友元成员函数
使类B中的成员函数成为类A的友元函数,这样类B的该成员函数就可以访问类A的所有成员了。
当用到友元成员函数时,需注意友元声明和友元定义之间的相互依赖,在该例子中,类B必须先定义,否则类A就不能将一个B的函数指定为友元。然而,只有在定义了类A之后,才能定义类B的该成员函数。更一般的讲,必须先定义包含成员函数的类,才能将成员函数设为友元。另一方面,不必预先声明类和非成员函数来将它们设为友元。
#include <iostream>
using namespace std;
class A; //当用到友元成员函数时,需注意友元声明与友元定义之间的互相依赖。这是类A的声明
class B
{
public:
void set_show(int x, A &a); //该函数是类A的友元函数
};
class A
{
public:
friend void B::set_show(int x, A &a); //该函数是友元成员函数的声明
private:
int data;
void show() { cout << data << endl; }
};
void B::set_show(int x, A &a) //只有在定义类A后才能定义该函数,毕竟,它被设为友元是为了访问类A的成员
{
a.data = x;
cout << a.data << endl;
}
int main(void)
{
class A a;
class B b;
b.set_show(1, a);
return 0;
}
友元小结:
在需要允许某些特定的非成员函数访问一个类的私有成员(及受保护成员),而同时仍阻止一般的访问的情况下,友元是可用的。
优点:
可以灵活地实现需要访问若干类的私有或受保护的成员才能完成的任务;
便于与其他不支持类概念的语言(如C语言、汇编等)进行混合编程;
通过使用友元函数重载可以更自然地使用C++语言的IO流库。
缺点:
一个类将对其非公有成员的访问权限授予其他函数或者类,会破坏该类的封装性,降低该类的可靠性和可维护性。
摘自:https://www.cnblogs.com/zhuguanhao/p/6286145.html
2、面试题
请写出 BOOL flag 与“零值”比较的 if 语句
if ( flag )
if ( !flag )
如下写法均属不良风格。
if (flag == TRUE)
if (flag == 1 )
if (flag == FALSE)
if (flag == 0)
请写出 float x 与“零值”比较的 if 语句。
千万要留意,无论是float 还是double 类型的变量,都有精度限制,都不可以用“==”或“!=”与任何数字比较,应该设法转化成“>=”或“<=”形式。(为什么?文章之后有详细的讨论,可参考)
假设浮点变量的名字为x,应当将
if (x == 0.0) // 隐含错误的比较
转化为
if ((x>=-EPSINON) && (x<=EPSINON))
其中EPSINON 是允许的误差(即精度)。
标准答案示例:
const float EPSINON = 0.00001;
if ((x >= - EPSINON) && (x <= EPSINON)
如下是错误的写法。
if (x == 0.0)
if (x != 0.0)
请写出 char *p 与“零值”比较的 if 语句。
标准答案:
if (p == NULL)
if (p != NULL)
如下写法均属不良风格。
if (p == 0) // 容易让人误解p是整型变量
if (p != 0)
if (p) // 容易让人误解p是bool型变量
if (!p)