db = SQLiteDatabase.create(null);
}
else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory);
}
分析上述代码发现,当数据库名字为非空时,创建数据库或打开由mContext完成,这个mContext由SQLiteOpenHelper的构造函数传入:SQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version)。那么我们对于传入的context,重载其openOrCreateDatabase函数,使其将数据库创建到SD卡中就可完成我们的目标了~。
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* 数据库管理和维护类
**/
public class SdCardDBHelper extends SQLiteOpenHelper{
public static final String TAG = "SdCardDBHelper";
/**
* 数据库名称
**/
public static String DATABASE_NAME = "sddb.db";
/**
* 数据库版本
**/
public static int DATABASE_VERSION = 1;
/**
* 构造函数
*
* @param context 上下文环境
**/
public SdCardDBHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* 创建数据库时触发,创建离线存储所需要的数据库表
*
* @param db
**/
@Override
public void onCreate(SQLiteDatabase db) {
Log.e(TAG, "开始创建数据库表");
try{
//创建用户表(user)
db.execSQL("create table if not exists user" +
"(_id integer primary key autoincrement,name varchar(20),password varchar(20),role varchar(10),updateTime varchar(20))");
Log.e(TAG, "创建离线所需数据库表成功");
}
catch(SQLException se){
se.printStackTrace();
Log.e(TAG, "创建离线所需数据库表失败");
}
}
/** 更新数据库时触发,
*
* @param db
* @param oldVersion
* @param newVersion
**/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//db.execSQL("ALTER TABLE person ADD COLUMN other STRING");
}
}
重载的openOrCreateDatabase在sd卡上创建数据库的Context
import java.io.IOException;
import android.content.Context;
import android.content.ContextWrapper;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;
/**
* 用于支持对存储在SD卡上的数据库的访问
**/
public class DatabaseContext extends ContextWrapper {
/**
* 构造函数
* @param base 上下文环境
*/
public DatabaseContext(Context base){
super(base);
}
/**
* 获得数据库路径,如果不存在,则创建对象对象
* @param name
* @param mode
* @param factory
*/
@Override
public File getDatabasePath(String name) {
//判断是否存在sd卡
boolean sdExis
题目描述:
最长不重复子串(Longest No Repeat String,LNRS)就是从一个字符串中找到一个连续子串,该子串中任何两个字符都不能相同,且该子串的长度是最大的。
分析:
解法一:动态规划
动态规划就是用来解决这种最优化问题,关于字符串的很多有趣的问题如最长公共自序列,最长上升子序列等都可以用动态规划来解,这道题我的第一想法也是动态规划。
动态规划的核心在于寻找最优子结构,对于一个字符,如果他与他前面的最长不重复子串都没有相同的字符,那么他也可以加入这个子串中,构成一个新的子串。即对于字符数组a[],dp表示以a为结尾的最长不重复子串长度,dp[0] = 1,最后取dp中的最大值即可。代码如下:
2 #include <cstdlib>
3 #include <string.h>
4
5 using namespace std;
6 char in[10001];
7
8 int dp[10001];
9
10 int LNRS_dp(char *in)
11 {
12 int i, j;
13 int len = strlen(in);
14 int last = 0; // 上一次最长子串的起始位置
15 int maxlen,maxindex;
16 maxlen = maxindex = 0;
17
18 dp[0] = 1;
19 for(i = 1; i < len; ++i)
20 {
21 for(j = i-1; j >= last; --j) // 遍历到上一次最长子串起始位置
22 {
23 if(in[j] == in)
24 {
25 dp = i - j;
26 last = j+1; // 更新last_start
27 break;
28 }else if(j == last) // 无重复
29 {
30 dp = dp + 1;//长度+1
31 }
32 }
33 if(dp > maxlen)
34 {
35 maxlen = dp;
36 }
37 }
38 return maxlen;
39 }
40
41 int main()
42 {
43 freopen("1530.in","r",stdin);
44 freopen("1530.out","w",stdout);
45
46 while(scanf("%s",in)!=EOF)
47 {
48 printf("%d\n",LNRS_dp(in));
49 }
50 return 0;
51 }
显然这个方案是O(n2)的复杂度,且对字符种类没有限制。
解法二:Hash
很多情况下,在描述一个字符串时,都是英文字母组成的字符,因此可能出现的元素是有限的(26个),因此就有了第二种想法,Hash。
这种想法在于使用一个大小为26的数组visited[]记录每个字符是否出现,然后枚举最长不重复子串的起点。代码如下:
2 {
3 char visited[26];
4 int i, j;
5 int maxlen = 0;
6
没有评论:
发表评论