ASIHTTPRequest学习(二)
Handling compressed responses, and compressing request bodies
Using gzip to handle compressed response data
Using gzip in ASIHTTPRequest
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// YES is the default, you can turn off gzip compression by setting this to NO
[request setAllowCompressedResponse:YES];
[request startSynchronous];
BOOL *dataWasCompressed = [request isResponseCompressed]; // Was the response gzip compressed?
NSData *compressedResponse = [request rawResponseData]; // Compressed data
NSData *uncompressedData = [request responseData]; // Uncompressed data
NSString *response = [request responseString]; // Uncompressed data as a string
}
这里设置allowCompressedResponse为true,ASIHTTPRequest会添加一个Accept-Encoding header到request表明我们接收gzipped类型的数据。如果是压缩的,那么使用responseData or responseString会解压缩数据。也可以调用rawResponseData来获取原始的数据。
这里因为服务器端有可能给的是zip,这样自动解压缩可能会丢数据,所以可以考虑直接接收数据后自己解压缩。
On-the-fly inflating of gzipped responses
By default, ASIHTTPRequest will wait until a request finishes to inflate (uncompress) a gzipped response. By setting a request’s shouldWaitToInflateCompressedResponses property to NO, you can tell ASIHTTPRequest to inflate the data as is comes in. In some circumstances, this may result in a small speed boost, as data can be processed while a request is waiting for more of the response.
This feature may be especially useful if you need to parse the response with a streaming parser (eg an XML or JSON parser). With this option enabled, you can feed inflated data directly to your parser as it comes in by implementing request:didReceiveData: in your delegate.
Note that when shouldWaitToInflateCompressedResponses is set to NO, the raw (compressed) data will be discarded. See the comments in ASIHTTPRequest.h for more info.
Using gzip to compress request bodies
New in v1.0.3 is gzip compression for request bodies. Using this feature, your applications can compress the content of POST / PUT operations by setting shouldCompressRequestBody to YES. shouldCompressRequestBody is NO by default.
Apache’s mod_deflate can automatically inflate (decompress) gzipped request bodies when configured with SetInputFilter DEFLATE (More info). This approach works for CGI content, but not when you are using an Apache module built as a RESOURCE filter (such as mod PHP). In these cases, you need to inflate the data yourself.
ASIHTTPRequest cannot check if a server can accept a gzipped request body or not. Use this feature only if you are certain that the server you are talking to will understand a gzipped body.
Avoid gzipping content that is in a format that already uses compression (eg JPEG/PNG/GIF/PDF/SWF), you may well find the gzipped version is larger than the original.
Resuming interrupted downloads
- (IBAction)resumeInterruptedDownload:(id)sender
{
NSURL *url = [NSURL URLWithString:
@"http://allseeing-i.com/ASIHTTPRequest/Tests/the_great_american_novel.txt"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
NSString *downloadPath = @"/Users/ben/Desktop/my_work_in_progress.txt";
// The full file will be moved here if and when the request completes successfully
[request setDownloadDestinationPath:downloadPath];
// This file has part of the download in it already
[request setTemporaryFileDownloadPath:@"/Users/ben/Desktop/my_work_in_progress.txt.download"];
[request setAllowResumeForFileDownloads:YES];
[request startSynchronous];
//The whole file should be here now.
NSString *theContent = [NSString stringWithContentsOfFile:downloadPath];
}
断点续传功能,需要设置allowResumeForFileDownloads为yes,你必须设置临时的文件路径,因为新的数据会追加到原来的路径中去。然后会移动到downloadDestinationPath当下载完成后。
Resuming works by reading the size of the file at temporaryFileDownloadPath, and then requesting the rest of the file using a Range: bytes=x HTTP header.
ASIHTTPRequest does not check for the presence of a Accept-Ranges header (because of the overhead of an additional HEAD request), so only use this feature when you are certain the that server you are connecting to supports partial downloads for the resource you want to download.
也就是说也要服务器支持断点续传功能才可以。
Streaming request bodies directly from disk
As of v0.96, ASIHTTPRequest can use files on disk as the request body. This means that it is no longer necessary to hold the request body in memory, which should result in a drastic reduction in memory usage for large POST/PUT operations.
There are several ways you can use this feature:
ASIFormDataRequests
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"foo" forKey:@"post_var"];
[request setFile:@"/Users/ben/Desktop/bigfile.txt" forKey:@"file"];
[request startSynchronous];
ASIFormDataRequests automatically use this feature when you use setFile:forKey:. The request will create a temporary file that will contain the full post body. Files are written a bit at a time to the relevant part of the body. The request is created using CFReadStreamCreateForStreamedHTTPRequest, using a read stream on the file as the source.
Regular ASIHTTPRequests
If you know your request is going to be large, turn on streaming from disk on the request:
[request setShouldStreamPostDataFromDisk:YES];
In the example below, we add NSData objects to the post body one at a time. There are two methods for doing this - adding data from memory (appendPostData:), or appendPostDataFromFile: to add the contents of a file.
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setShouldStreamPostDataFromDisk:YES];
[request appendPostData:myBigNSData];
[request appendPostDataFromFile:@"/Users/ben/Desktop/bigfile.txt"];
[request startSynchronous];
In this example, we want to PUT a large file directly. We set setPostBodyFilePath ourselves, ASIHTTPRequest will use this file as the post body.
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:@"PUT"];
[request setPostBodyFilePath:@"/Users/ben/Desktop/another-big-one.txt"];
[request setShouldStreamPostDataFromDisk:YES];
[request startSynchronous];
IMPORTANT: You should not use setPostBody in the same request as any of the methods described above - they are mutually exclusive. setPostBody should only be used if you want to build the request body yourself, and plan on keeping the request body in memory.
Using a download cache
The API for ASIDownloadCache and ASICacheDelegate has changed in v1.8, and you will need to update your code if you are updating from v1.7.
In particular, the options available for cache
policies are different, and you can now combine multiple cache policies
for a single request.
ASIHTTPRequest can automatically store downloaded data in a cache for use later. This can be helpful in many situations:
- You want to have access to the data when there is no internet connection and you can’t download it again
- 想访问数据但是没有网络连接不能再次下载
- You want to download something only if it has changed since you last downloaded it
- 只有在数据发生变化后才选择下载
- The content you are working with will never change, so you only want to download it once
- 下载的数据只要求下载一次之后不会再改动
In previous versions of ASIHTTPRequest, handling the above situations
would have meant storing the data manually yourself. Using a download
cache may eliminate the need for writing any local storage mechanism
yourself in some situations.
ASIDownloadCache is a simple URL cache that can be used for caching
the response of GET requests. To be eligible for response caching,
requests must succeed (no error), and the server must have returned a
200 OK HTTP response code, or, as of v1.8.1, a 301, 302, 303 and 307
redirect status code.
Turning on the response cache is easy:
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
After you’ve done this, all requests will use the cache automatically. If you prefer, you can set individual requests to use the shared cache on a case by case basis:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
You aren’t restricted to a single cache - you can create as many caches as you like. When you create a cache yourself, you must set the storage path for the cache - this should be a folder you have write access to:
ASIDownloadCache *cache = [[[ASIDownloadCache alloc] init] autorelease];
[cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];
// Don't forget - you are responsible for retaining your cache!
[self setMyCache:cache];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[self myCache]];
About cache policies
Cache policies are the main way you control when information is stored in the cache, and when cached data will be used in preference to downloading the data again.
The cache policy of individual requests can be controlled using a request’s cachePolicy property. Cache policies are defined using a bitmask, so you can combine multiple options to create the policy you want:
// Always ask the server if there is new content available,
// If the request fails, use data from the cache even if it should have expired.
[request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy];
You can use the following options to define a request’s cache policy:
ASIUseDefaultCachePolicy | The default cache policy. When you set a request to use this, it will use the cache’s defaultCachePolicy. ASIDownloadCache’s default cache policy is ‘ASIAskServerIfModifiedWhenStaleCachePolicy’. You should not combine this with other options. |
---|---|
ASIDoNotReadFromCacheCachePolicy | Requests will not read from the cache when using this option. |
ASIDoNotWriteToCacheCachePolicy | Requests will not save to the cache when using this option. |
ASIAskServerIfModifiedWhenStaleCachePolicy | This is the default cache policy for ASIDownloadCaches. When using this, requests will first look to see if a cached response is available in the cache. If there is no cached data, the request will proceed as normal. If there is and the cached data has not expired, the request will use the cached data without contacting the server. If the cached data has expired, the request will perform a conditional GET to see if an updated version is available. If the server says the cached data is current, cached data will be used, and new data will not be downloaded. In this case, the cache’s expiry time will be updated to match the new expiry date from the server. If the server provided updated content, it will be downloaded, and the new data and expiry written to the cache. |
ASIAskServerIfModifiedCachePolicy | This is the same as ASIAskServerIfModifiedWhenStaleCachePolicy, except that requests will always ask the server if updated data is available. |
ASIOnlyLoadIfNotCachedCachePolicy | When using this option, cached data will always be used if it exists, even if it should have expired. |
ASIDontLoadCachePolicy | When using this option, requests will succeed only if a response is already cached. If no response for a request is cached, the request will stop, and no error will be set on the request. |
ASIFallbackToCacheIfLoadFailsCachePolicy | When using this option, requests will fallback to cached data if the request fails. If cached data is used after a failure, the request will succeed without error. You would normally use this option in combination with others, as it is only useful for specifying the behaviour to use when something goes wrong. |
When you set the defaultCachePolicy property of a cache, all requests
that use that cache will use that cache policy unless they have a
custom cache policy set on themselves.
About storage polices
Storage policies allow you to define how long a cache will store a
particular response. ASIHTTPRequest currently supports two storage
policies:
ASICacheForSessionDurationCacheStoragePolicy is the
default. Responses will be stored only for the duration of the session,
and will be removed the first time the cache is used, or when
[ASIHTTPRequest clearSession] is called.
With ASICachePermanentlyCacheStoragePolicy, cached responses are stored permanently. To use this storage policy, set it on a request:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
To manually clear the cache, call clearCachedResponsesForStoragePolicy:, passing the storage policy for the cached data you want to remove:
[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
Other cache-related features
// When you turn shouldRespectCacheControlHeaders off, the cache will store responses even if the server
// has explictly asked for them not be be cached (eg with a cache-control or pragma: no-cache header)
[[ASIDownloadCache sharedCache] setShouldRespectCacheControlHeaders:NO];
// Set secondsToCache on the request to override any expiry date for the content set by the server, and store
// this response in the cache until secondsToCache seconds have elapsed
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setSecondsToCache:***]; // Cache for 30 days
// After a request has run, didUseCachedResponse will return YES if the response was returned from the cache
[request didUseCachedResponse];
// Ask the cache for a path to store the response. This is the most efficient way to use a download cache,
// since data doesn't have to be copied into the cache when the request completes.
[request setDownloadDestinationPath:
[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request]];
Writing your own cache
If you already have a download cache and would like to plug it in to ASIHTTPRequest, or you prefer to write your own, have your cache implement the ASICacheDelegate protocol.
Throttling bandwidth
As of v1.0.7, ASIHTTPRequest can throttle the bandwidth used by all requests to prevent it going over a user-defined limit. This may help iPhone applications that send or receive large amounts of data to make it through the app store review process.
Throttling works by using a global limit (in bytes) for how much data can be received or transmitted in one second. All requests share this limit. As they send or receive data, ASIHTTPRequest keeps track of how much data has been sent or received in the last second. If one request exceeds the limit, any others running will also have to wait for the remainder of the current measurement period.
On iOS, you can tell ASIHTTPRequest to automatically turn throttling on when using a WWAN (GPRS/Edge/3G) connection, and it will automatically turn it off when switching to WiFi.
// Will limit bandwidth to the predefined default for mobile applications when WWAN is active.
// Wi-Fi requests are not affected
// This method is only available on iOS
[ASIHTTPRequest setShouldThrottleBandwidthForWWAN:YES];
// Will throttle bandwidth based on a user-defined limit when when WWAN (not Wi-Fi) is active
// This method is only available on iOS
[ASIHTTPRequest throttleBandwidthForWWANUsingLimit:];
// Will prevent requests from using more than the predefined limit for mobile applications.
// Will limit ALL requests, regardless of whether Wi-Fi is in use or not - USE WITH CAUTION
[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
// Log how many bytes have been received or sent per second (average from the last 5 seconds)
NSLog(@"%qi",[ASIHTTPRequest averageBandwidthUsedPerSecond]);
IMPORTANT: Read this before enabling bandwidth throttling:
- Bandwidth throttling should be considered an experimental feature: Use at your own risk.
- Do not set the bandwidth limit too low - it’s probably best not to set it below ASIWWANBandwidthThrottleAmount
- The actual bandwidth used by your application will always be slightly more than the limit you have set, because the measured bandwidth does not include the bandwidth used by HTTP headers.
- The value of ASIWWANBandwidthThrottleAmount is not official, as far as I know, no bandwidth limit has been officially published.
- You should not turn on bandwidth throttling unless your application is likely to send or receive large amounts of data. It may be best to turn it only only while performing requests that download or upload a large amount of data, and leave it off at all other times.
- It probably goes without saying, but I make no guarantee your app won’t be rejected for using excessive bandwidth when you turn on throttling.
Client certificates support
If your server requires the use of client certificates, as of v1.8 it is now possible to send them with your request.
// Will send the certificate attached to the identity (identity is a SecIdentityRef)
[request setClientCertificateIdentity:identity];
// Add an additional certificate (where cert is a SecCertificateRef)
[request setClientCertificates:[NSArray arrayWithObject:(id)cert]];
There is a helper function in ClientCertificateTests.m in the iPhone / iPad sample app that can create a SecIdentityRef from PKCS12 data (this function only works on iOS).
Working with Proxies
ASIHTTPRequest can detect system proxy settings and automatically apply them to requests. As of v1.0.6, it also supports PAC file proxy configuration, and authenticating proxies.
By default, ASIHTTPRequest will attempt to detect proxy settings automatically. However, should you wish, you can manually set proxy settings:
// Configure a proxy server manually
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:@"192.168.0.1"];
[request setProxyPort:];
// Alternatively, you can use a manually-specified Proxy Auto Config file (PAC)
// (It's probably best if you use a local file)
[request setPACurl:[NSURL URLWithString:@"file:///Users/ben/Desktop/test.pac"]];
Authenticating proxies
On Mac OS, ASIHTTPRequest can auto-detect credentials used for authenticating proxies if they are specified in System Preferences. On iOS, ASIHTTPRequest cannot auto-detect the credentials used for authenticating proxies, so you either have to set them manually, use delegation to ask your controller / the user for appropriate credentials, or let ASIAuthenticationDialog ask the user for them. Once valid proxy credentials have been obtained, they are stored in the keychain (when useKeychainPersistence is on) and are automatically reused.
Manually specifying credentials for the proxy
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:@"192.168.0.1"];
[request setProxyPort:];
// Set a username and password for authenticating proxies
[request setProxyUsername:@"bencopsey"];
[request setProxyPassword:@"password"];
// For NTLM proxies, you can also set the domain (NTLM proxies are untested!)
[request setProxyDomain:@"la.la.land"];
Using delegation to ask for proxy credentials
This works in the same way as using delegates to provide credentials for regular authentication, except that your delegate must respond to proxyAuthenticationNeededForRequest: (formerly proxyAuthorizationNeededForRequest:).
Using the built-in authentication dialog (currently iOS only)
New in v1.0.8 is the ASIAuthenticationDialog class. This can be used to ask the user for credentials for authenticating webservers and proxies.
If your delegate does not respond to proxyAuthenticationNeededForRequest:, by default, ASIHTTPRequest will show a dialog prompting the user to supply credentials. It appears by default for proxy servers so that all apps using ASIHTTPRequest can work with authenticating proxies without any additional effort on the part of the developer.
The proxy authentication dialog will not appear for synchronous requests.
If you prefer not to use the proxy authentication dialog, either implement proxyAuthenticationNeededForRequest: in your proxy, or set shouldPresentProxyAuthenticationDialog to false (in which case your application will not be able to connect to authenticating proxies). If you want to change the look and feel, subclass ASIHTTPRequest, and override showProxyAuthenticationDialog to show your custom dialog or ASIAuthenticationDialog subclass.
Miscellaneous features
Customising the user agent
To set the user agent your app will use, do this:
[ASIHTTPRequest setDefaultUserAgentString:@"MyApp 1.0"]
If you do not set a user agent, ASIHTTPRequest will create one for you. An example (for a Mac OS application):
My Application 1.0 (Macintosh; Mac OS X 10.5.7; en_GB)
You can also set the user agent on a per-request basis:
[request setUserAgent:@"MyApp 1.0"]
Continuing a request when your app enters the background on iOS
// iOS 4+ only
[request setShouldContinueWhenAppEntersBackground:YES];
Monitoring network activity
// Log the average bandwidth used (in bytes) per second over the last 5 seconds
NSLog(@"%llu",[ASIHTTPRequest averageBandwidthUsedPerSecond]);
if ([ASIHTTPRequest isNetworkInUse]) {
// ASIHTTPRequest has requests in progress that are using the network
}
Disabling automatic updates to the network activity indicator (iOS only)
By default, ASIHTTPRequests will show the network activity indicator (in the status bar) on iOS devices when requests are using the network. If you prefer to manage this yourself, you can disable these updates:
[ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO];
Automatically retry requests when they time out
Make requests retry a maximum of 2 times if they encounter a timeout:
[request setNumberOfTimesToRetryOnTimeout:];
Configuring persistent connections
By default, ASIHTTPRequest will attempt to keep connections to a server open so that they can be reused by other requests to the same server (this generally results in significant speed boost, especially if you have many small requests). Persistent connections will be used automatically when connecting to an HTTP 1.1 server, or when the server sends a keep-alive header. Persistent connections are not used if the server explicitly sends a ‘Connection: close’ header. Additionally, ASIHTTPRequest will not use persistent connections for requests that include a body (eg POST/PUT) by default (as of v1.8.1). You can force the use of persistent connections for these request by manually setting the request method, then turning persistent connections back on:
[request setRequestMethod:@"PUT"];
[request setShouldAttemptPersistentConnection:YES];
Many servers do not provide any information in response headers on how long to keep a connection open, and may close the connection at any time after a request is finished. If the server does not send any information about how long the connection should be used, ASIHTTPRequest will keep connections to a server open for 60 seconds after any request has finished using them. Depending on your server configuration, this may be too long, or too short.
If this timeout is too long, the server may close the connection before the next request gets a chance to use it. When ASIHTTPRequest encounters an error that appears to be a closed connection, it will retry the request on a new connection.
If this timeout is too short, and the server may be happy to keep the connection open for longer, but ASIHTTPRequest will needlessly open a new connection, which will incur a performance penalty.
// Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes
[request setPersistentConnectionTimeoutSeconds:];
// Disable persistent connections entirely
[request setShouldAttemptPersistentConnection:NO];
Forcing the use of HTTP 1.0
[request setUseHTTPVersionOne:YES];
Disabling secure certificate validation
You may wish to use this for testing purposes if you have a self-signed secure certificate. I recommend purchasing a certificate from a trusted certificate authority and leaving certificate validation turned on for production applications.
[request setValidatesSecureCertificate:NO];
ASIHTTPRequest学习(二)的更多相关文章
- emberjs学习二(ember-data和localstorage_adapter)
emberjs学习二(ember-data和localstorage_adapter) 准备工作 首先我们加入ember-data和ember-localstorage-adapter两个依赖项,使用 ...
- ReactJS入门学习二
ReactJS入门学习二 阅读目录 React的背景和基本原理 理解React.render() 什么是JSX? 为什么要使用JSX? JSX的语法 如何在JSX中如何使用事件 如何在JSX中如何使用 ...
- TweenMax动画库学习(二)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
- Hbase深入学习(二) 安装hbase
Hbase深入学习(二) 安装hbase This guidedescribes setup of a standalone hbase instance that uses the local fi ...
- Struts2框架学习(二) Action
Struts2框架学习(二) Action Struts2框架中的Action类是一个单独的javabean对象.不像Struts1中还要去继承HttpServlet,耦合度减小了. 1,流程 拦截器 ...
- Python学习二:词典基础详解
作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...
- Quartz学习--二 Hello Quartz! 和源码分析
Quartz学习--二 Hello Quartz! 和源码分析 三. Hello Quartz! 我会跟着 第一章 6.2 的图来 进行同步代码编写 简单入门示例: 创建一个新的java普通工程 ...
- SpringCloud学习(二):微服务入门实战项目搭建
一.开始使用Spring Cloud实战微服务 1.SpringCloud是什么? 云计算的解决方案?不是 SpringCloud是一个在SpringBoot的基础上构建的一个快速构建分布式系统的工具 ...
- DjangoRestFramework学习二之序列化组件、视图组件 serializer modelserializer
DjangoRestFramework学习二之序列化组件.视图组件 本节目录 一 序列化组件 二 视图组件 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 序列化组 ...
随机推荐
- 团队项目-任务分解[Alpha0]
团队项目-任务分解[Alpha0] 标签(空格分隔): 团队博客 适用范围: 本文档 适用对象 团队全体成员 适用时间 alpha阶段第一周计划 10.24-10.28 适用内容 目标.分工.时长估计 ...
- C# 命名管道
有些场合需要高效率,进行线程间通信,可以使用 C#命名管道.
- Github - Unity3d-Timers
https://github.com/pointcache/Unity3d-Timers Unity3d-Timers Timer class with various behaviors About ...
- NIO--1
1.为什么不直接用jdk NIO(1) API繁杂(2) 原始NIO可靠性不是很高.可靠性包括:断开重连,网络闪断,半包读写,失败缓存(3) NIO 的epoll BUG会导致多路复用器Selecto ...
- redis cluster管理工具redis-trib.rb详解
redis cluster管理工具redis-trib.rb详解 来源 http://weizijun.cn/2016/01/08/redis%20cluster%E7%AE%A1%E7%90%86% ...
- ndk开发-ffmpeg编译
进入模拟器shell: D:\Users\zhouhaitao\AppData\Local\Android\sdk\platform-tools\adb shell ndk编译链接静态库: LOCAL ...
- BZOJ1233 [Usaco2009Open]干草堆tower 【单调队列优化dp】
题目链接 BZOJ1233 题解 有一个贪心策略:同样的干草集合,底长小的一定不比底长大的矮 设\(f[i]\)表示\(i...N\)形成的干草堆的最小底长,同时用\(g[i]\)记录此时的高度 那么 ...
- vue-cli安装sass
npm install node-sass --save npm install sass-loader --save 也可以使用淘宝镜像 npm install -g cnpm --registry ...
- 《c程序设计语言》读书笔记-3.4-数字转字符串
#include <io.h> #include <stdio.h> #include <string.h> #include <stdlib.h> # ...
- 2016"百度之星" - 初赛(Astar Round2A)HDU 5695 拓扑排序+优先队列
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...