2013年9月29日星期日

Android中使用SQLiteOpenHelper管理SD卡中的数据库 - esrixa

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
Android中使用SQLiteOpenHelper管理SD卡中的数据库 - esrixa  阅读原文»

使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限:
(1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databases中(可使用Eclispe的DDMS查看)。
(2)如果无法获取Root权限,则无法直接查看创建的数据库。
鉴于上述限制及实际需要,打算使用SQLiteOpenHelper管理SD卡上的数据库,通过研究SQLiteOpenHelper的源码,发现其创建或打开数据库的代码位于getWritableDatabase()函数中(getReadableDatabase本身也是调用了getWritableDatabase):
if (mName == null) {
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卡中就可完成我们的目标了~。

对应的SQLiteOpenHelper实现类SdCardDBHelper
import android.content.Context;
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.File;
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中的最大值即可。代码如下:

1 #include <cstdio>
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[]记录每个字符是否出现,然后枚举最长不重复子串的起点。代码如下:

1 void LNRS_hash(char* s)
2 {
3 char visited[26];
4 int i, j;
5 int maxlen = 0;
6

没有评论:

发表评论