C++知识点(一)

String

构造函数

1
2
3
4
5
6
7

string();
string(size_type length,char ch);
string(const char *str);
string(const char *str,size_type length);
string(string &str, size_type index, size_type length);
string(input_iterator start,input_iterator end);

例子:

1
2
3
4
5
6
7
8
9
10
11
string str1( 5, 'c' );
string str2( "Now is the time..." );
string str3( str2, 11, 4 );
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
%
ccccc
Now is the time...
time
%

操作符(operators)

1
2
3
4
5
6
7
8
9
==
>
<
>=
<=
!=
+
+=
[]

可以用+或者+=连接两个字符串

append

1
2
3
4
5
6
7
语法:
basic_string &append(const basic_string &str);
basic_string &append(const char *str);
basic_string &append(const basic_string &str,size_type index,size_type len);
basic_string &append(const char *str,size_type num);
basic_string &append(size_type num,char ch);
basic_string &append(input_iterator start,input_iterator end);

例子:

1
2
3
4
5
string str = "Hello World";
str.append( 10, '!' );
cout << str << endl;
显示
Hello World!!!!!!!!!!

赋值(assign)

1
2
3
4
5
basic_string &assign(const basic_string &str);%用str为字符串赋值
basic_string &assign(const char *str);%用str为字符串赋值
basic_string &assign(const char *str,size_type num);%用str的开始num个字符为字符串赋值
basic_string &assign(const basic_string &str,size_type index,size_type len);%用str的字串为字符串赋值,从index开始,长度为len
basic_string &assign(size_type num,char ch);%用num个字符ch为字符串赋值

例子

1
2
3
4
5
string str1, str2 = "War and Peace";
str1.assign( str2, 4, 3 );
cout << str1 << endl;
显示
and

end和begin

1
2
iterator begin();
iterator end();

begin(),end()函数返回一个迭代器,指向字符串的第一个元素/最后一个元素

c_str

1
const char *c_str();

c_str()函数返回一个指向正规C字符串的指针,内容与本字符串相同

data

1
const char *data();

data()函数返回指向自己的第一个字符的指针

empty

1
bool empty();

如果字符串为空empty()返回true,否则返回false;

erase

1
2
3
iterator erase(iterator pos);//删除pos指向的字符,返回下一个字符的迭代器
iterator erase(iterator start, iterator end);//删除从start到end的所有字符,返回删除的最后一个字符的下一个字符的迭代器
basic_string &erase(size_type index=0,size_type num=npos);//删除从index索引开始的num个字符,返回*this

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
string s("So, you like donuts, eh? Well, have all the donuts in the world!");
cout << "The original string is '" << s << "'" << endl;

s.erase( 50, 14 );
cout << "Now the string is '" << s << "'" << endl;

s.erase( 24 );
cout << "Now the string is '" << s << "'" << endl;

s.erase();
cout << "Now the string is '" << s << "'" << endl;
显示
The original string is 'So, you like donuts, eh? Well, have all the donuts in the world!'
Now the string is 'So, you like donuts, eh? Well, have all the donuts'
Now the string is 'So, you like donuts, eh?'
Now the string is ''

find

1
2
3
4
size_type find( const basic_string &str, size_type index );\\从index开始查找,返回str在字符串第一次出现的位置
size_type find( const char *str, size_type index );\\从index开始查找,返回str在字符串第一次出现的位置
size_type find( const char *str, size_type index, size_type length );\\返回str在字符串中第一次出现的位置(从index开始查找,长度为length)
size_type find( char ch, size_type index );\\返回字符ch在字符串中第一次出现的位置(从index开始查找)

例子

1
2
3
4
5
6
string str1( "Alpha Beta Gamma Delta" );
unsigned int loc = str1.find( "Omega", 0 );
if( loc != string::npos )
cout << "Found Omega at " << loc << endl;
else
cout << "Didn't find Omega" << endl;

substr

功能:从一个字符串复制一个从指定位置开始,并具有指定长度的子字符串。
basic_string substr(size_type _ Off = 0,size_type _ Count = npos) const;
参数
_ Off 所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0.
_ Count 复制的字符数目
返回值 一个子字符串,从其指定的位置开始
例子:

1
2
3
4
5
string x="Hello_World";
/*默认截取从0到npos.重载原型为string substr(_off=0,_count=npos);npos一般表示为string类中不存在的位置,_off表示字符串的开始位置,_count截取的字符的数目*/
cout<<x.substr()<<endl;
cout<<x.substr(5)<<endl;//截取x[5]到结尾,即npos.重载原型为string substr(_off,_count=npos)
cout<<x.substr(0,5)<<endl;//以x[0]为始,向后截取5位(包含x[0]),重载原型string substr(_off,_count)

atoi,stoi,strtoi区别

atoi和strtoi都是c里面的函数,他们都可以将字符串转为int,它们的参数都是const char,因此在用string时,必须调用c_str()方法将其转为char的字符串.或者atof,strtod将字符串转为double,他们都从字符串开始寻找数字或者正负号或者小数点,然后遇到非法字符终止,不会报异常:

1
2
3
4
5
6
7
8
9
int main() {
using namespace std;
string strnum=" 232s3112";
int num1=atoi(strnum.c_str());
long int num2=strtol(strnum.c_str(),nullptr,10);
cout<<"atoi的结果为:"<<num1<<endl;
cout<<"strtol的结果为:"<<num2<<endl;
return 0;
}

stoi是string库中的函数,它的参数是string

1
2
3
4
5
6
7
8
9
int main() {
using namespace std;
string strnum="XDEADbeE";
int num1=atoi(strnum.c_str());
int num2=stoi(strnum);
cout<<"atoi的结果为:"<<num1<<endl;
cout<<"stoi的结果为:"<<num2<<endl;
return 0;
}

atoi,itoa,atof,_ ttoi等

itoa—-integer to ASCII—将整形转换成字符串
atof—-ascii to float—字符串转换成浮点型

atol—-ascii to long—-字符串转换成长整形

gcvt—-浮点型转换成字符串(四舍五入)

strtod—-字符串转换成浮点型

strtol—-字符串转换成长整形

strtoul—字符串转换成无符号长整形

toascii—-将整形转换成合法的ASCII码字符

_ ttoi—-可以将CString转换成整形

_ itot_s—-将int转换成char*

冒号:

for(auto n1:result):
cout<<n1;

result是vector的形式,auto n1:result是将result里的每个元素依次赋给n1.

什么是内存泄漏?面对内存泄漏和指针越界,有哪些方法?通常用哪些方法来避免和减少这类错误?

用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元即为内存泄漏.
对指针赋值的时候应该注意被赋值的指针需不需要释放
动态分配内存的指针最好不要再次赋值

解释C++中静态函数和静态变量

(1)类静态数据成员在编译时创建并初始化:在该类的任何对象建立之前就存在,不属于任何对象,而非静态类成员变量属于对象所有的.类静态数据成员只有一个拷贝,为所有此类的对象所共享.
(2)类静态成员函数属于整个类,不属于某个对象,由该类所有对象共享

  1. static 成员变量实现了同类对象间信息共享
  2. static 成员类外存储,求类大小,并不包含在内
  3. static 成员是命名空间属于类的全局变量,存储在data区的rw段
  4. static成员只能类外初始化
  5. 可以通过类名访问(无对象生成时亦可),也可以通过对象访问

  6. 静态成员函数的意义:不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装

  7. 静态成员函数只能访问静态数据成员.原因:非静态成员函数,在调用this指针时被当作参数传进.而静态成员函数属于类,而不属于对象,没有this指针.

对C++内存的了解

  1. 栈——由编译器自动分配释放
  2. 堆——一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收
  3. 全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域. 程序结束释放.
  4. 另外还有一个专门放常量的地方。程序结束释放。
  5. 程序代码区,存放二进制代码
    在函数体中定义的变量通常是在栈上,用malloc,calloc,realloc等分配内存的函数分配的得到的就是在堆上.在所有函数体外定义的是全局量,加static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效.另外,函数中的”adgfdf”这样的字符串存放在常量区.

指针和引用的区别?

  1. 指针是一个变量,只不过这个变量存储的是一个地址,指针指向内存的一个存储单元。而引用仅是一个别名
  2. 引用使用时无需解引用( * ),指针需要解引用
  3. 引用只能在定义时被初始化一次,之后不可变;指针可变
  4. 引用没有const,指针有const (引用如前所述是一个别名而非变量,所以它不能有const,但是const可以有引用)
  5. 引用不能为空,指针可以为空
  6. “sizeof引用”得到的是所指的变量(对象)的大小,而”sizeof指针”得到的是指针本身的大小
  7. 指针和引用自增(++)运算意义不一样
  8. 指针可以有多级,但是引用只能是一级(int **p;合法而int&&a是不合法的)
  9. 从内存分配上看:程序为指针变量分配内存区域,而引用不需要分配内存区域

贪婪算法

贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。

贪心算法的基本要素

  1. 贪心选择性质。所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。
    动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以 自顶向下 的方式进行,以迭代的方式作出相继的贪心选择,每作一次贪心选择就将所求问题简化为规模更小的子问题。
    对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

  2. 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

贪心算法的基本思路

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到算法中的某一步不能再继续前进时,算法停止。
该算法存在问题:

  1. 不能保证求得的最后解是最佳的;
  2. 不能用来求最大或最小解问题;
  3. 只能求满足某些约束条件的可行解的范围。
    实现该算法的过程:
    从问题的某一初始解出发;
    while 能朝给定总目标前进一步 do
       求出可行解的一个解元素;
    由所有解元素组合成问题的一个可行解;
    1
    2
    3
    1.将优化问题转换成这样一个问题,即先做出选择,再解决剩下的一个子问题。
    2.证明原问题总是有一个最优解是贪心选择的得到的,从而说明贪心选择的安全。
    3.说明在做出贪心选择后,剩下的子问题具有这样一个性质。即如果将子问题的最优解和我们所做的贪心选择联合起来,可以得到一个更加负责的动态规划解。

数字组合问题!

设有N个正整数,现在需要你设计一个程序,使他们连接在一起成为最大的数字,例3个整数 12,456,342 很明显是45634212为最大,4个整数 342,45,7,98显然为98745342最大

程序要求:输入整数N 接下来一行输入N个数字,最后一行输出最大的那个数字!

-------------本文结束感谢您的阅读-------------