编程刷题的一些技巧

刷题当中遇到的一些编程技巧

1.如何获得一个二维数组的行数和列数;
int m=matrix.size(),n=matrix[0].size();
2.记住 在一个二维数组当中,第一步是判断数组是否为空
int m=matrix.size();   //取出行的数目
if(m==0) return false;  //如果行0 ,说明是个空数组,不为0,接下来才是取列数
int n=matrix[0].size(); //取出多少列

另外一种判空的方法是 推荐使用第二种

if(matrix.empty()||matrix[0].empty()) return false;
3.二分法的常用套路

在进行二分的时候,左右两边的边界值可以取以下两种

int left=0;int right=vector.size()-1;  
或者
int begin=0 ;int right=vector.size()-1;

在取中间值的时候,主因以下两种格式

int mid=left+((right-left)>>1); //移位操作更加好
//int mid=(left+right)/2    尽量不要用这种

接下来就是重要的循环体 了

方法1

 while(left<=right)  //直到边界范围内没有数值  那么这样你就要用一种方法使得能够使得左右范围交叉
 //那么使用的方法就是以下结构
 {
     int mid=left+((right-left)>>1);
     if( 中间值 > target )  right=mid-1;
     else if( 中间值 < target) left=mid+1;
     else return true;
 }
return false;  //当没有一个相等值,那么所有边界就会不断的加减,以至于边界交叉->跳出->返回错误
     
4.当你想返回一个临时的 向量

这是一种初始化的思想

return vector<int>{-1,-1};
return vector<int> {};
5.分割字符串的方法
  • 通过stl实现

首先了解 find 函数

原型:size_t find ( const string& str, size_t pos = 0 ) const;
功能**:查找子字符串第一次出现的位置。**
参数说明:str为子字符串,pos为初始查找位置,默认从头开始。
返回值:找到的话返回第一次出现的位置,否则返回string::npos

例如:

size_t pos = strs.find("!");
size_t pos = strs.find("!", 5) //从第5个位置开始找

同时,还有一个find_first_of(),find_last_of()不是全匹配,而find()是全匹配

其功能是:查找子串中的某个字符最先/最后出现的位置

  while(pos!=string::npos)  {操作字符串}  npos为字符串的最后一位

其次,了解字符串和int之间的转换

int----->string
 eg: string a=to_string(5);
-----------------------------------------------------------
string------->int    //建议使用前两种
eg1:  string b="532"  ;  int a=atoi(b.c_str());
eg2:  string b="532"  ;  int a;  stringstream(b)>>a;
eg3:  string b="532"  ;  int a;  sscanf(b.c_str(),"%d",&a);

了解 substr 函数

原型:string substr ( size_t pos = 0, size_t len = npos ) const;
功能:获得子字符串。
参数说明:pos为起始位置(默认为0),len为字符串长度(默认为npos)
返回值:子字符串

string x = strs.substr(0,len);  //获得从0位置开始到len长度的字符串
 string s("12345asdf");
 string a = s.substr(0,5);  //the answer is "12345"
  • 还有一种使用strtok() 函数的方法 以后有时间探究

    c语言中还有一种方法分割字符串:

    line=GET /hello.c http.1001.1  //如何分割这三个字符串
     //利用正则表达式
     sscanf(line,"%[^ ]%[^ ]%[^ ]",method,path,protcol);//这样就可以把字符串分割
    还有就是可以利用strtok的方法
    
6.字符串与字符的操作

首先对于一个字符串,你知道其长度吗?

string a = "12345";
a.length();   输出的结果为5  			a.size();     输出的结果为5			
sizeof(char)  输出的结果为1			sizeof(a)	  输出的结果为28  为啥为28

同理

string a = "12345";	
char* ptr=&a[0];       //a[0]输出为1
cout << ptr<< endl;  //输出为  12345
cout <<*ptr<<end; 	//输出为  1   将ptr向后移动5位后将指向‘\0’,也就是a[5]

此外,string还有抹除的操作

string a = "12345";
a.erase(2,1);         //a="12"
a.erase(1,3)		//a="15"
7.如何测试一个程序的时间
clock_t start, finish; 
double totaltime;
start = clock();//墙上时间
.....程序......
finish = clock();
totaltime= (double)(finish - start) / CLOCKS_PER_SEC;每秒的滴答数
    可以参考APUE210页
8.二维向量的初始化
bool 类型            其它类型类似
   vector<vector<bool>> dp(一维大小);
	for (int i = 0; i < dp.size(); i++) {
		dp[i].resize(二维大小, true);//初始化的值  默认初始化为false
	} 
输出:
    1  1  1  1  1  1  1
	1  1  1  1  1  1  1
	1  1  1  1  1  1  1
	1  1  1  1  1  1  1 
9.判断一个字符时候是数字
自己判断
if(c >='a' && c<='z' ||  c >='A' && c<='Z'))  printf("是字母\n");
调用库函数:
 if(isdigit(c) != 0)    printf("是数字\n") ;
10.优先级队列(大根#小根)的设置
 //数据类型为   listnode类
class mycompare {        //首先设置一个比较器
  public:
	  bool operator()(ListNode p1, ListNode p2)const {
		  return p1.val > p2.val;    //这儿是个小根堆
	  }
  };
//开始设置
priority_queue<ListNode,vector<ListNode>,mycompare> smallheap;

//数据类型为 int   可以直接设置
//系统默认的大根堆,其实这儿根本就不用设置小根堆,因为我们直接存相反数就可以了
priority_queue<int, vector<int>, greater<int>> small;
priority_queue<int, vector<int>, less<int>> big;
//我们知道pair类型是进行双关键字进行排序,比如pair<int,string>如果我们按照默认系统大根堆进行插入,就会是双关键字排序的结果,int和string都排序
//但是如果我们设置了以上的排序方法,那么就是有第一个关键字进行排序。
11.怎样设置vector的排序呢?
//降序排序
sort(vInts.begin(), vInts.end(),greater<int>());
//升序排序
sort(vInts.begin(), vInts.end(),less<int>());
11.大写字母变小写互相变换怎么变?
//'A'=65
//'a'=97
char a='a';
a^=32   a='A';//
12.求一个数的质数
for(int i=2;n>1;i++)  //从2开始进行榨干
    while(n%i==0)  res+=i;    //当while成立  说明i是一个n的质数。那么可以把它取出来

扩展:求一个数的约束 很简单啦 直接就一个循环
那么一个数的约数是一个奇数,那么那么这个数一定是n^2 一个平方数

13.怎样去最小公倍数呢

求ab得最小公倍数
int x=a*b/_gcd(a,b);
求abc的最小公倍数
int y=x*c/_gcd(x,c);
13.如何判断两个数的异号性
//方法一  在数据的不大的时候,可以使用相乘
//下面介绍另外一种方法 
 bool minus=false;
 if(a<0) minus=!miuns,a=-a;
 if(b<0) miuus=!minus,b=-b;
14.求最大公约数 gcd
//第一种:递归 思想 辗转相除法
int gcd(int a,int b)
{
   if(b == 0)  return a;
   return gcd(b,a%b);
}
//第二种:非递归
 int gcd(int a,int b){
    while(b){
        int t = b;
        b = a%b;
        a = t;
    }
    return a;
} 
15.不要对 a.size()这种做加减法
//因为这种情况 size()是一个无符号整数,当和int做加减法的时候,如果产生了一个负数,就会是一个很大的数。比如-1;
16.stringstream 的应用
//函数是从一个字符串里面提取东西  比如一个sting  为“laign rui ai shang  chai  jin"
//我们想要提取里面的单词  就可以使用这种方法

stringstream raw(str);
vector<string> words;
string word;
while(raw>>word) words.push_back(word);
17.对于map和unordered_map不用迭代器遍历
for(auto x:map)   //map<string ,int>
{
    string a=x.first;
    int b=x.second;
}
18.使用unordered_multiset
//unordered_multiset能够记录重复的值
unordered_multiset<int> hash;
hash.insert(1);
hash.insert(1);
//如果要进行删除 需要注意  如果直接删除就会把所有的值删除,所以我们需要找一个迭代器来一个一个的删
hash.erase(1) //两个都没有了
auto it =hash.find(1);
hash,erase(it)  //只删除了一个
19.vector用迭代器删除的问题(腾讯问过这种问题)
在利用iter进行删除的时候,比如 vector<int> st;
   for(auto itr=st.begin();itr!=st.end();itr++){
       st.erase(itr);   XXXX //这种方法是不可取的,因为itr都被删除了,就不能继续使用了
      //正确做法:
      itr=st.erase(itr);
      //也可以使用(自增、自减)
      st.erase(itr++)
   }

如果vector中存储的元素是指针,那么erase()或者clear()并不会删除指针指向的对象或者内存空间,要小心内存泄漏问题。可以先删除指针指向的内容,然后在删除vector中的元素。如下:

for(.....)
{
    delete(*itr);
    (*ter)==NULL;
}
20. C++ 上取整和下取整的转换
//C++没有上取整的操作     那么要求a/b的上取整可以写成   (a+b-1)/b;
21. 如果使用一些容器的东西 不想处理边界值,可以在两边加上哨兵
22.如何去替代我们的goto语句
在编程中,我们一般都不允许使用goto语句,但是我们就可以使用do-while(0)替代;
 do{
     ....
     break;
     .....
 }while(0)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值