C/C++之路
文章平均质量分 71
介绍基本的C/C++知识,同时介绍简单的C/C++小项目
ArchyLi
一个学习路上人。当然还差很多。
展开
-
稀疏矩阵的压缩存储
#include #include using namespace std;templateclass SparseMatrix{public: // 稀疏矩阵的压缩存储 SparseMatrix(int* array, size_t row, size_t col, const T& invalid) : _row(row) , _col(col) , _inval原创 2017-05-09 18:12:40 · 712 阅读 · 0 评论 -
两个栈实现一个队列
栈:先进后出的一种数据结构。队列:先进先出的一种数据结构。此时如果我们先有一个栈是不够的,我们只能把先入栈的元素后出来,后面入栈的元素先出来。这是我们便想如何才能实现一个先进先出的结构呢。看下图:我们先把元素倒入S1栈中,在把S1栈中的元素逐个压栈到S2里面,再从S2出栈,即可达到先入栈的元素先出。此时我们可以有一个小优化,最后一个元素X1可不入S2减少一次压栈的操作。原创 2017-07-21 16:58:47 · 466 阅读 · 0 评论 -
【每日一题】替换字符串中的空格为$$$。要求时间复杂度为O(N)
题目:替换字符串中的空格为$$$。要求时间复杂度为O(N)例如:将"talk is cheap show me the code"替换。为"talk$$$is$$$cheap$$$show$$$me$$$the$$$code"。这道题类似和剑指offer一书中面试题4:替换空格思路是一样的。题目要求时间复杂度为O(N),而我们一般从前向后的思路时间复杂度为O(n^2),所以原创 2017-07-21 17:12:48 · 563 阅读 · 0 评论 -
两个队列实现一个栈
栈:先进后出队列:后进先出方法一:如何用两个队列实现一个栈呢?我们可以把一个队列里面的内容放入第二个队列里面,此时要剩余一个,这剩下的一个可以直接出栈,再把队列2里面的元素放回队列1, 重复即可达到栈的要求#include#include using namespace std;template class Cstack{public: Cstack(void)原创 2017-07-22 13:09:06 · 572 阅读 · 0 评论 -
【每日一题】实现一个栈Stack,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值的操作)的时间复杂度为O(1)
这道题有两种实现方式方法一:用两个栈来实现两个栈实现的主要思路是,一个栈存放数据,一个栈存放最小值。压栈操作:(1)我们先向S1压栈一个数据(2)再向S1压入第二个数据,如果此时栈S2为空,并且把需要压栈的元素data和S2的栈顶元素进行比较,如果此时需要压栈的元素小于等于S2栈顶元素,把元素也压入栈2,否则不用管出栈操作:判断S1栈顶元素与S2栈顶元素是否相等,相原创 2017-07-22 14:45:03 · 3341 阅读 · 0 评论 -
【每日一题】查找一个字符串中第一个只出现两次的字符。要求时间复杂度为O(N),空间复杂度为O(1)
题目:将"talk is cheap show me the code"替换。查找一个字符串中第一个只出现两次的字符。如:“abcdefabcdefabc”中第一个只出现两次为‘d’,要求时间复杂度为O(N),空间复杂度为O(1)本题我们很容易想到两次遍历,及外面一个大循环里面一个小循环直接遍历,可是题目要求时间复杂度为O(N),空间复杂度为O(1)。因此我们采用如下的方法解决。创原创 2017-07-22 16:04:34 · 1408 阅读 · 1 评论 -
关于阶乘的面试题总结
阶乘方面的题一直是我最近不太明白的点,因此我便总结了几个关于阶乘方面的面试题供探讨。面试题:一、给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。二、求N!的二进制表示中最低位1的位置。对于第一道题,一般人的思路会是想着求完N!之后再来看,此时就要考虑是不是溢出的问题,但是我们换一个思路想一想,想一下有什么数字相乘可以等原创 2017-07-22 21:24:07 · 1101 阅读 · 0 评论 -
关于const知识点总结
1、基本描述定义变量的限定符,表示变量值不可改变const int a = 1024;a = 1024;//错误,不能向const对象写值注意:const对象必须初始化。由于const创建后不可更改,所以必须初始化。(定义一个不可修改的默认值完全无意义)const int i = get_size();//正确const int j = 1024;//正确const int k;原创 2017-07-29 20:29:30 · 868 阅读 · 1 评论 -
两个集合用单链表存储,分别求出集合的差集和并集(单链表求差集并集)
一、集合求交集题目:已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。 例如,若集合A = { 5,10,20,15,25,30 },集合B = { 5,15,35,25 },完成计算后A = { 10,20,30 }。 链表结点的结构类型定义如下: struct node { int elem;原创 2017-08-01 12:39:00 · 7259 阅读 · 0 评论 -
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern “C”?
一、extern简介首先我们用一句话来形容extern的作用:解决名字匹配问题,实现C/C++混合编程。extern是C/C++语言表明函数和全局变量作用范围的关键字,其声明的函数和变量可以在本模块或其他模块中使用。通常我们在模块的头文件中对本模块提供给其他模块引用的函数或全局变量用关键字extern声明。被extern “C”修饰的变量和函数是按照C语言方式编译和连接的。C++是一种面向对象的语言原创 2017-10-30 17:36:24 · 1230 阅读 · 0 评论 -
关键字static总结
一、static修饰变量与函数static修饰变量包含了局部变量和全局变量。一般函数内部的变量放在栈区,但是会随着函数的周期而被释放。由函数内部new产生的动态数据则存放在堆区,静态数据则存放在全局数据区,全局数据区的数据并不会随着函数的退出而是放空间。(1)static修饰全局变量static写在全局变量前,该变量就被定义为一个静态全局变量#include <iostream> using n原创 2017-11-05 01:01:08 · 1119 阅读 · 0 评论 -
C++实现复杂链表的复制
一、什么是复杂链表复杂链表的每个结点具有三个成员,分别是存放数据的data和指向下一个结点的指针和指向随机节点的指针。 复杂结点的结构:template <class T>struct ListNode{ T data; ListNode<T>* next; ListNode<T>* random; ListNode(const T& d) :d原创 2017-11-07 00:25:43 · 1966 阅读 · 0 评论 -
大数据处理
大数据处理并不要求手写代码,更重要的是叙述出来思路和方法,主要的解题思路有以下两个:方法:看能否用特殊的数据结构解决(位图、布隆过滤器、堆(TOP K 问题))哈希切分题目⒈ 给一个超过100G大小的log file,log中存着ip地址,设计算法找到出现次数最多的ip地址?解决方法:哈希切分。将100G的文件分成1000份,通过同一个散列函数映射到相应的文件,此时同一个ip一定会映射到同一原创 2017-11-14 22:03:00 · 461 阅读 · 0 评论 -
如何定义一个只能在栈上生成对象的类
这道题主要考察我们对于C++的语法的理解和运用的程度。本文主要给出了两种方法实现。方法一:分析:如果我们建立对象只能在栈上生成而不能在堆上生成,那么需要考虑以下几点:当我们用new操作符时候,才会在堆上生成对象,所以我们需要让它无法使用。将operator new()设为私有即可。代码如下: class A { private : void * operator new原创 2017-11-14 22:27:18 · 347 阅读 · 0 评论 -
如何定义一个只能在堆上生成对象的类
这道题主要考察我们对于C++的语法的理解和运用的程度。在C++中,类的对象建立分为两种,一种是静态建立,如A a;另一种是动态建立,如A* ptr=new A;这两种方式是有区别的。静态建立一个类对象,是由编译器为对象在栈空间中分配内存,是通过直接移动栈顶指针,挪出适当的空间,然后在这片内存空间上调用构造函数形成一个栈对象。使用这种方法,直接调用类的构造函数。动态建立类对象,是使用new运算符将原创 2017-11-14 22:48:13 · 381 阅读 · 0 评论 -
命名空间的理解
一、为什么要有命名空间一个工程的完成,往往由不同的人来共同完成,此时就有可能出现一个问题,不同的人写的函数名字会和另外一个人写的函数名字相同,此时哪一个函数是我们需要的呢? 所以我们为了解决这样的冲突,便采用了命名空间的方法,所谓的命名空间便是由用户自定义一个作用域,在不同的命名空间作用域内并不会互相影响。二、命名空间的定义命名空间是建立一些互相冲突的作用域,把一些全局实体分隔开。命名空间存放的实原创 2017-11-16 00:43:05 · 834 阅读 · 0 评论 -
C++中防止一个类被继承
一、思路在C++的继承里面我们知道,子类的构造函数会调用父类的构造函数,子类的析构函数会调用父类的析构函数,因此我们便想办法禁止子类调用父类的构造函数和析构函数即可,因此提出了如下两种方法。二、方法①构造函数与析构函数设置为私有我们把父类的构造函数和析构函数定义为私有成员,此时子类便不可调用父类的构造函数和析构函数,因此便达成了防止一个类被继承的目的,但是此时又出现一个问题,我们如何区构造一个类对象原创 2017-11-18 12:07:08 · 2172 阅读 · 1 评论 -
判断机器大小端的两种实现方式
一、为什么会有大小端之分这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小原创 2017-11-18 15:12:31 · 8633 阅读 · 0 评论 -
C++中四种强制转换
一、简介C++中存在四种强制类型转换,分别是static_cast 、const_cast 、 dynamic_cast 、reinterpret_cast二、存在原因我们直到在C语言中有强制类型转换,可以转换成合理的类型,那么我们为什么要在C++中引入四种强制类型转化的概念呢? 由于新类型的强制类型转换可以提供更好的强制控制转换过程,一旦当程序员使用了四种强制类型转换,其他的人读程序的时原创 2017-11-24 17:07:29 · 1582 阅读 · 2 评论 -
C语言中二分查找(折半查找)
二分査找也称折半査找,其优点是查找速度快,比较次数少,平均性能好,但是有一个缺点,缺点就是要求所要査找的数据必须是有序序列。该算法的基本思想是将所要査找的序列的中间位置的数据与所要査找的元素进行比较,如果相等,则表示査找成功,否则将以该位置为基准将所要査找的序列分为左右两部分。接下来根据所要査找序列的升降序规律及中间元素与所查找元素的大小关系,来选择所要査找元素可能存在的那部分序列,对其采用同样的原创 2016-12-11 10:51:51 · 7024 阅读 · 1 评论 -
C语言布尔、整形、浮点、指针变量与”零值”比较的if语句
在学习C语言中的if语句中,我遇到了变量与零值进行比较的一些问题,当比较的数值为浮点变量时,不能直接用 if (x == 0.0)或者 if (x != 0.0) ,由于float和 double类型的数据都是有精度限制的,所以0.0000...0001=0(超过一定的精度限制),所以有时候会得到错误的结果。原创 2016-10-16 11:56:55 · 3439 阅读 · 0 评论 -
C语言switch case 语句中能否使用continue 关键字?
在C语言的学习中,我学习到switch case语句,我发现不能使用continue关键字。代码如下:#include int main(){ int a; printf("input integer number: "); scanf("%d",&a); switch (a) { case 1:printf("Monday\n"原创 2016-10-20 20:19:24 · 7159 阅读 · 2 评论 -
C语言扫雷
实现代码如下:1、sweep.h#define _CRT_SECURE_NO_WARNINGS 1#ifndef __MINE_H__#define __MINE_H__enum op{ EXIT, PLAY};#include #include #include #include #define COLS 11#define ROWS 1原创 2016-10-26 11:38:00 · 1750 阅读 · 1 评论 -
解决_CRT_SECURE_NO_WARNINGS 警告
问题:我们在程序中遇到_CRT_SECURE_NO_WARNINGS 警告信息,让人烦恼。如下我提供了三个解决方式:方法一、右击项目->属性->C/C++->预处理器->预处理器定中添加 _CRT_SECURE_NO_WARNINGS 这个预定义。如下图方法二、打开VS的目录下的 (newc++file.cpp)添加如下文字#defi原创 2016-10-31 17:50:24 · 4587 阅读 · 0 评论 -
C语言递归与非递归实现求第n个斐波那契数
一、非递归实现第N个菲波那切数列:程序如下:#include int fib(int n){ int a1 = 1; int a2 = 1; int a3 = 0; if( n <= 2 ) return 1; else { while(n > 2) { a3 = a1 + a2; a1 = a2; a2 = a3; n--; }原创 2016-11-10 20:49:15 · 3105 阅读 · 0 评论 -
使用C语言打印不同星号图案
一、画图方法画一个图,通常可以选择如下方法:1、画每一个图形,填充形状覆盖的像素。2、对于图像中每个像素,采样该像素覆盖了什么形状。第一种就是光栅化(rasterization)算法,第二种包括光线追踪(ray tracing)、光线步进(ray marching)等算法。第二种做法可以理解为设计一个数学函数,这种方式可以用较少的代码画出复杂的形状。如果要输出文本模式,原创 2016-11-19 00:45:26 · 11206 阅读 · 1 评论 -
写冒泡排序可以排序一个整型数组。
题目:写冒泡排序可以排序一个整型数组。代码如下:#include void Bubble_Sort(int arr[], int len){ int i = 0; int j = 0; int temp = 0; for(i = 0; i < len-1; i++) { for(j = 0; j < len-1; j++) { if(arr[j] > arr[原创 2016-11-20 15:39:18 · 869 阅读 · 0 评论 -
char的取值为什么是-128~127
首先,我们要知道计算机里面所有的数都是用补码表示的,正数的补码是其本身,负数的补码是原码的反码加一。127这个数值很好理解,char占一个字节(byte),含有8个bit位.我们知道数字在计算机中是以二进制来存储的,最高位是符号位,0为正1为负所以当char表示为正数时:表示的数字有2的七次方 2^7=128个 ,从+0~127。 0 : 0000 00001原创 2016-12-02 23:55:42 · 3120 阅读 · 0 评论 -
简单的通讯录——第一版
实现效果如下图:此C语言通讯录用来存储1000个人的信息,每个成员的信息包括有姓名、性别、年龄、电话、住址。这次我们C语言通讯录V1.0提供的功能有:1、添加联系人2、删除联系人3、修改联系人4、查看所有联系人的信息5、以名字排序所有联系人7、清空所有联系人8、退出系统总体过程实现:首先定义一个结构体,存储其中一位成员的信息,信息包括原创 2016-12-04 17:34:37 · 974 阅读 · 0 评论 -
C语言请实现字符串循环右移函数。列如字符串“abcdefghi”向右移2位就是“hiabcdefg”
题目:请实现字符串循环右移函数。列如字符串“abcdefghi”向右移2位就是“hiabcdefg”。函数原型为:void RightLoopMove(char *pstr,unsigned short steps)函数参数说明: pStr: Point to a ‘\0’ terminated string steps: The rotate shift原创 2016-12-11 10:53:05 · 5836 阅读 · 0 评论 -
简单的通讯录——第二版(动态版)
简单的通讯录——第二版(动态版)实现效果如下:此C语言通讯录和第一版一样,不过是动态增长通讯录的容量来达到存储的目的。同样,我们的通讯录包括了每个成员的信息有性别,年龄,电话和住址。这次我们C语言通讯录V2.0提供的功能有:1、添加联系人2、删除联系人3、修改联系人4、查看所有联系人的信息5、以名字排序所有联系人7、清空所有联系人8、退出原创 2016-12-14 01:14:40 · 553 阅读 · 0 评论 -
顺序表的实现
这篇文章我们来整理下与顺序表有关的内容首先说明一下顺序表的概念: 顺序表是计算机在内存中以数组形式保存的一种线性表,它用一组地址连续的存储单元依次存储数据元素的线性结构。它是一种最简单的数据结构,除了线性表中的第一个和最后一个元素之外,其他元素都是以直线首尾相接。顺序表详解一、定义顺序表中的结构体:typedef struct SeqList{ DataT原创 2017-01-13 22:58:08 · 757 阅读 · 0 评论 -
【C++】operator关键字(重载操作符)
operator是C++的关键字,它和运算符一起使用,表示一个运算符函数,理解时应将operator=整体上视为一个函数名。 这是C++扩展运算符功能的方法,虽然样子古怪,但也可以理解:一方面要使运算符的使用方法与其原来一致,另一方面扩展其功能只能通过函数的方式(c++中,“功能”都是由函数实现的)。 一、为什么使用操作符重载?对于系统的所有操作符,一般情况下,只支持基本数据类转载 2017-02-16 18:57:45 · 641 阅读 · 0 评论 -
【C++】复数类的实现
复数类的运算有加减乘除四个,下面我们来逐步分析这几个运算。一·加法运算设z1=a+bi,z2=c+di是任意两个复数,则它们的和是 (a+bi)+(c+di)=(a+c)+(b+d)i;此处需要注意的是返回值的类型为复数complex。二.减法运算设z1=a+bi,z2=c+di是任意两个复数,则它们的差是(a+bi)-(c+di)=(a-c)+(b原创 2017-02-16 20:34:27 · 16895 阅读 · 3 评论 -
【C++】C++中几种测试程序运行时间的方法
关于C++中计算时间的一些总结一、使用GetTickCount()函数GetTickCount()是一个函数,可以把它理解为打点计时器。GetTickCount()是通过计算从函数开始运行计时,直到函数运行结束所求出函数的运行时间。它返回从操作系统启动所经过的毫秒数,返回值:DWORD头文件:winbase.h函数原型:DWORD GetTickCount(void)原创 2017-02-17 10:20:40 · 27451 阅读 · 0 评论 -
【C++】模板与泛型编程
首先我提一个问题,什么是泛型编程?泛型编程:是编写与类型无关的逻辑代码,是代码复用的一种手段。模板是泛型编程的基础。模板又可以分为下面两个:范型,也就是任何类型,也就是不依赖于具体的数据类型通常,我们的操作都是都是依赖于具体的数据类型的,比如int add(int a,int b){ return a+b;}缺点就是只要有新类型出现,我们就要重新添加原创 2017-03-14 18:06:03 · 928 阅读 · 0 评论 -
结构体在内存中的对齐规则
一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。例一: #include using namespace std; struct转载 2017-03-18 11:16:04 · 676 阅读 · 0 评论 -
【C++】继承总结
一、继承的概念继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有的类的特性的基础上进行一个扩展,可以增加其功能。二、继承的定义格式三、继承关系与访问限定符总结:1、公有继承基类的成员,全部是基类的成员。2、保护和私有继承基类的成员都变成各自的继承。3、基类的私有成员无法继承。4、使用关键字class时默认的继承方式是private原创 2017-03-19 00:03:25 · 616 阅读 · 0 评论 -
【C++】冒泡排序的C++实现
C语言的冒泡排序如下:void Bubble_Sort(int arr[], int len) { int i = 0; int j = 0; int temp = 0; for(i = 0; i < len-1; i++) { for(j = 0; j < len-1; j++) {原创 2017-03-20 22:38:09 · 1015 阅读 · 0 评论 -
【C++】面向对象类成员函数的重载、覆盖与隐藏
重载:重载就是一个相同的作用域内实现相同的操作,但是操作的对象不相同特征成员函数重载:相同的范围(相同的作用域)函数名字相同参数不同(类型不同,个数不同,顺序不同)注意:返回值类型不同不算函数重载覆盖:覆盖就是面向对象的多态,指的是派生类函数覆盖基类函数。特征:不同的范围(不同的作用域,分别是基类和派生类)参数相同函数名字必须相同原创 2017-03-22 00:21:15 · 463 阅读 · 0 评论