“24点游戏是一种使用扑克牌来进行的益智类游戏,游戏内容是:从一副扑克牌中抽去大小王剩下52张,任意抽取4张牌,把牌面上的数(A代表1)运用加、减、乘、除和括号进行运算得出24。每张牌都必须使用一次,但不能重复使用。 有些组合有不同种算法,例如要用2,4,6,12四张牌组合成24点,可以有如下几种组合方法: 2 + 4 + 6 + 12 = 24 4 × 6 ÷ 2 + 12 = 24 12 ÷ 4 × (6 + 2) = 24 当然,也有些组合算不出24,如1、1、1、1 和 6、7、8、8等组合。” --题目描述来自wikipedia:http://zh.wikipedia.org/wiki/24%E7%82%B9。 请完成函数can24,4张牌如果可以组成24点,返回1,不能则返回0。 友情提醒: 注意以下这些组合: 1 1 1 10 不可以; 6 6 6 6 可以; 5 5 5 1 可以,即可以用分数,如(5-1/5)*5 = 24; 1 1 1 11 可以;
完成功能函数即可:
#include <iostream> #include <string> #include <cmath> #include <sstream> using namespace std; const double wucha=1E-6; //浮点除法有精度损失 double num[4]; bool flag; //标记是否成功 void game24(int n){ if(n==1){ if(fabs(num[0]-24)<=wucha){ flag=1; return ; } } if(flag)return ; //找到满足的一组即可 for(int i=0;i<n;i++) { for(int j=i+1;j<n;j++) { double a,b; a=num[i]; b=num[j]; num[j]=num[n-1]; //用最后一个元素覆盖,注意这里的n在每次递归中是要递减的 num[i] = a + b; game24(n-1); num[i] = a - b; game24(n-1); num[i] = b -a; game24(n-1); num[i]=a*b; game24(n-1); if (b != 0) { num[i] = a / b; game24(n-1); } if (a != 0) { num[i] = b / a; game24(n-1); } num[i]=a; num[j]=b; //递归恢复 } } } int can24(int a, int b, int c, int d){ num[0]=double(a); num[1]=double(b); num[2]=double(c); num[3]=double(d); flag=0; game24(4); if(flag)return 1; else return 0; } int main() { cout<<can24(6,6,6,6)<<endl; cout<<can24(1,1,1,10)<<endl; //不可以 cout<<can24(5,5,5,1)<<endl; cout<<can24(1,1,1,11)<<endl; return 0; }
题目:
Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between).
For example:
Given binary tree {3,9,20,#,#,15,7},
3 / \ 9 20 / \ 15 7
return its zigzag level order traversal as:
[ [3], [20,9], [15,7] ]
代码如下:
void getleverorder(TreeNode *root,vector<vector<int> > &getnode,int i)
{
if(root!=NULL)
{
if(i>getnode.size())
{
vector<int> tmp;
tmp.push_back(root->val);
getnode.push_back(tmp);
}
else
{
getnode[i-1].push_back(root->val);
}
getleverorder(root->left,getnode,i+1);
getleverorder(root->right,getnode,i+1);
}
return;
}
void swap(vector<int> &tmp)
{
int n=tmp.size()-1,i=0;
while(i<n)
{
int t=tmp[i];
tmp[i++]=tmp[n];
tmp[n--]=t;
}
return;
}
vector<vector<int> > zigzagLevelOrder(TreeNode *root) {
vector<vector<int> > getnode;
int i=1;
getleverorder(root,getnode,i);
for(int i=0;i<getnode.size();i++)
{
if(i%2==1)
{
swap(getnode[i]);
}
}
return getnode;
}
话说我刚知道这词的时候还是十二年前…大约2001年,微软的.net刚出来的时候,这货就热了,只不过当年这货的标配通讯协议是SOAP。当年我觉得这货还是很方便的,但是在尝鲜过后,我根本没有兴趣将它用于实际的应用…它实在是太笨重了。
这种笨重包括几个方面:首先SOAP本身的数据结构就很啰嗦,加上XML就更啰嗦了。其次,各种实现技术在高层逻辑上的定义各有一套,实际上并不那么通用。最主要的是要用这货,需要带上太多的开发库什么的,而且用起来实在也没有传说中的那么方便。
说实话,这十二年来,我基本上就没见过像样的应用——听说过一些,也很少,评价普遍也不是很高。在web领域,它甚至未必有xml-rpc常见。
随着RESTful和JSON的流行,新的WebService模型已经成为了事实标准,那就是以标准HTTP请求构建RESTful的API结构,以JSON定义交换协议的数据结构,组成了新一代的轻量级WebService模型。
就目前来说,提供RESTful API已经成了很多网站的标配…即使你不提供开放平台服务,也要考虑到移动应用啊,没有比这更好的实现方案了——技术足够成熟(大网站都在用)、节约资源(大多数时候,这意味着性能更好)、简单轻量(需要学习的东西不多,依赖的东西也不多)。
更详细的理由可以参考一下CSDN的CTO范凯的这篇文章《Ruby社区应该去Rails化了》。
这其中最著名的应该是Facebook的开放平台,而应用最广泛的则是Twitter的API接口。国内的山寨版本就是像人人网、微博网之类的。
因为个人使用需要,我对Twitter的API有过一段时间研究,不过坦白说,Twitter的这套API定义得相当不够RESTful,要学习如何定义API,还是强烈建议学习foursquare的API v2(当前版本),这才是规范的RESTful实现…不过它们的API经常不定期微调,所以需要一个v参数,这点略不规范。
回到主题上,说了这么多关于RESTful WebService的话题,本文主要还是要介绍RESTful客户端的技术。
关于客户端对RESTful WebService的调用,有很多方法,理论上只要是支持标准HTTP请求的方法都可以用。比如我前两年在介绍OAuth 1.0a/OAuth 2.0的时候用的例子便是用PHP的curl库实现的。至于python就更方便了,除了自带的urllib之类,还有httplib什么的,但是最方便的还要算是requests。
但是对我来说,这还不够方便。
用过SOAP的人都知道,SOAP有个好东西叫做WSDL,通过导入这个东西,可以生成一个wrapper,使得远程调用的使用像本地方法调用一样简单,对于静态语言来说,还可以提供语法检查。
但是RESTful WebService就没有这种东西了,只有一份给人看的文档,还需要人工自己转成代码——当然通常服务端也会有提供参考实现的库,但总是不方便——因为每个服务商都有自己一套,现在API这么多,实现风格又各异,学起来太麻烦,还容易搞错。
要是再加上各种Authentication/Authorization,麻烦的事情就更多了。
于是我想到利用动态语言的动态性,对这些请求进行动态的wrapping,做了这个通用库。
基本的RESTful请求在谈论这个库的使用之前,先说一下基本的RESTful请求结构:
一般来说请求由这几个主要部分组成:HTTP请求方法(GET,POST,PUT,DELETE...),URI,参数。
除此之外,还可能用到的内容有:HTTP请求头,HTTP响应代码。
一个常见的例子类似这样:
GET http://api.yourserver.com/v1/objects/function?id=xxxx
或者:
GET http://api.yourserver.com/v1/objects/xxxx/function
其中的xxxx就是id参数
对于支持多种数据格式的WebService(如早期的Twitter和现在的饭否,都支持除JSON以外的XML和RSS两种格式),在URI上还会有格式后缀,如:
GET http://api.yourserver.com/v1/objects/xxxx/function.xml
而在如BasicAuth或Header方式的OAuth1.0a/2.0下,还需要操作HTTP请求头。出错的时候还需要处理HTTP响应代码。
这些都是不必要的麻烦。所以我做了这么个库试图解决这些问题。
我的目标是把这类的请求包装起来,通过标准的Python调用来实现。比如上面的请求可以简化为这样的Python代码:
api.object.GET_function(xxxx)
这样就方便多了。
RestClient库这个库就一个文件,包括两个方面:Auth和APIClient。
其中APIClient是一个wrapper,用于实现动态将python调用转为RESTful请求。Auth部分包括了常用的BasicAuth, OAuth1.0a, OAuth2.0三种认证方式。
对于那么多的API是不是需要对每个API去实现一个api类,对于每个API的那么多功能,是不是需要实现一堆的objects类和无数的function方法呢?那样不就跟服务端提供的库一样了嘛。
答案当然是不需要。
以饭否为例,实现一个饭否API只需要这么几行代码:
class Fanfou(APIClient): def __init__(self, client_key, client_secret, callback="", access_token=""): APIClient.__init__(self, AuthOAuth1("http://fanfou.com/oauth", client_key, client_secret, callback=callback, access_token=access_token), "http://api.fanfou.com", ['search', 'blocks', 'users', 'account', 'saved_searches', 'photos', 'trends', 'followers', 'favorites', 'friendships', 'friends', 'statuses', 'direct_messages'], "json")
关于其中的参数,简单解释一下:
父类APIClient需要五个参数:auth, api_url, object_list, postfix, ssl_verify
其中auth是一个auth对象,用来指定用哪种认证方式。api_url是指API请求的URL,即所有RESTful请求的URI最前面共同的那一部分。object_list是可选的,没有这一项的话,可以使用任意名字的object,如果有这个list,则只能使用这里列出的部分,建议提供这个参数,这样可以不用等到服务端返回404才知道搞错名字。postfix是格式后缀,如服务端不需要加后缀,这个参数可以不用。注意:没有json和空以外的其它选择,本库不支持XML或RSS格式。ssl_verify用于SSL证书检查,默认为True,但是因为requests似乎不是使用操作系统的证书体系,而是自己弄了一套,所以有些正常的SSL网站也会报SSL验证错误,另外对一些使用自签名证书的网站(理由你懂的),也需要将这个参数设置为False才不报错。
这里使用了OAuth1.0a,AuthOAuth1需要四个参数:auth_url, client_key, client_secret, callback, access_token。auth_url是请求认证的调用的根URL,中间二者来自于你的服务端所提供,callback是回调你的客户端时用的URL。具体参见OAuth 1.0a规范文档或我以前的文章说明。最后一个access_token则是对于预先保存过access_token的情况下,可以直接使用,不用每次重新登录授权。
使用的方法也很简单,关于OAuth 1.0a的请求部分原理参见我以前的文章,这里不再重复,使用方法参见项目的demoweb.py这个web服务程序例子。
假设已经完成登录,取得了有效的access_token,可以这样调用饭否API:
fan = Fanfou(client_key, client_secret, access_token=access_token) # 前两个参数来自服务端所提供,最后一个参数来自登录后取得的access_token user = fan.account.GET_verify_credentials() # 调用 GET http://api.fanfou.com/account/verify_credentials # user 对象就是取得的调用结果
本项目已经发布在bitbucket:https://bitbucket.org/raptorz/restclient
目前我已经提供了饭否、Foursquare和Google(只包含登录功能)等的三个API包装,再增加别的包装也是很容易的事情。