My Little World

learn and share


  • 首页

  • 分类

  • 标签

  • 归档

  • 关于
My Little World

字符串(串结构)

发表于 2017-02-07

字符串

定义:串是由0个或多个字符组成的有限序列,又名字符串
1.空串:没有字符,直接由””表示
2.主串与子串:”hello”是”helloworld”的子串,”helloworld”是”hello”主串
3.字符串比较:比较字符串里每个字符的ASCII码大小,没有意义,一般看是否相等
4.存储结构
顺序存储:用一组地址连续的存储单元来存储串中的字符序列,
按照预定义大小,为每个定义的字符串变量分配一个固定长度的存储区,一般用定长数组来定义
链式存储:不常用
5.BF算法:
有两个字符串S和T,长度为N和M,首先S[1]和T[1]比较,若相等,则再比较S[2]和T[2],一直到T[M-1]为止;
若S[1]和T[1]不等,则T向右移动一个字符的位置,再依次进行比较
6.字符串模式匹配:依据BF算法,S是主串,T是子串这种定位操作即字符串模式匹配

BF算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var string1="hellohannahworld";
var string2="hannah";
function BF(str1,str2){
var i = 0;
var j = 0;
while(i<str2.length){
while(j<str1.length){
if(str2[i]==str1[j]){
if(i==str2.length-1){
var temp=j-str2.length+1;
console.log("字符串匹配的起始位置为"+temp);
return
}
j++;
i++;
}else{
if(i>0){
i=0;
}
if(i==0){
j++
}
}
}
}
console.log("两字符串一点也不匹配!")
return
}
BF(string1,string2);
My Little World

使用Git Bash建立本地仓库并同步github仓库

发表于 2017-02-03

建立本地仓库

1.选择仓库存放位置,新建文件夹,用作本地仓库
2.打开Git bash,cd 切换路径到该文件夹
3.执行以下命令

1
2
3
4
5
echo "该项目简短说明" >> README.md     ##输入“该项目简短说明”内容到README.md文件
git init
git add README.md ##将提交的文件(README.md)的信息添加到索引库
git commit -m "第一次提交" ##依据索引库中的内容来进行文件的提交
##同时提交更改描述“第一次提交”

以上步骤完成本地仓库建立和将文件提交到本地仓库的工作

建立远成仓库

1.登录github账号,点击右上角“+”,选择“New repository”
2.填写仓库名称,简单描述
3.为避免与本地仓库READMD.md冲突,初始化时不勾选“Initialize this repository with a README”
4.点击“Create repository”,生成远程仓库

同步仓库

1.点击“Clone or download”, 复制远程仓库地址
2.执行以下代码

1
2
git remote add origin 远程仓库地址     ##将本地仓库推送到远成仓库
git push -u origin master ##将本地仓库推送到远程分支

以上步骤即完成本地仓库同步到远程仓库

执行git remote时,
若出现提示出错信息:fatal: remote origin already exists.
则先输入

1
git remote rm origin ##删除远程仓库

再执行推送语句 “git remote add origin 远程仓库地址”

更新远成仓库

若对本地仓库进行了修改
git add <文件名> 只是添加一个文件
git add . 可添加全部仓库文件
若执行“git add .”时,总出现警告:warning: LF will be replaced by CRLF in XXXXXXXXXXXXXX.
可执行语句 “git config core.autocrlf false”
添加完文件后执行提交操作
git commit -m “”
最后推送到远程仓库
git push -u origin master

[资源共享](http://www.cnblogs.com/len0031/p/5831571.html)

My Little World

循环队列

发表于 2017-02-02

假溢出

queue9
循环队列的容量是固定的,并且它的对头和队尾指针都可以随着元素出入队列而发生改变,
这样循环队列逻辑上就好像是一个环形存储空间,但在实际内存中,是不可能有真正的环形存储区的,
我们只是用顺序表模拟逻辑上的循环
因此,为防止发生假溢出,当我们采用循环队列时,front和rear不断加1,即使超出了地址范围,
也会自动从头开始,判断溢出,可采用取模处理
(rear+1)%QueueSize
(front+1)%QueueSize
取模即取余数,取得的值永远不会大于除数

定义一个循环队列

queue12

1
2
3
4
5
6
# define MAXSIZE 100
typedef struct{
ElemType *base; ##存放内存分配基地址,也可以用数组存放
int front;
int rear;
}

初始化一个循环队列

1
2
3
4
5
6
7
initQueue(cyclQueue *q){
q->base = (ElemType *)malloc(MAXSIZE sizeof(ElemType));
if(!q->base){
exit(0);
}
q->front = q->rear = 0;
}

入队列操作

1
2
3
4
5
6
7
insertQueue(cyclQueue *q,ElemType e){
if((q->rear+1)%MAXSIZE == q->front){
return; ##队列已满
}
q->base[q->rear] = e;
q->rear = (q->rear+1)%MAXSIZE;
}

出队列操作

1
2
3
4
5
6
7
DeleteQueue(cyclQueue *q,ElemType e){
if(q->rear == q->front){
return; ##队列为空
}
*e = q->base[q->front];
q->front = (q->front+1)%MAXSIZE;
}
My Little World

递归

发表于 2017-02-02

递归

1.把有一个直接调用自己或通过一系列的调用语句间接的调用用自己的函数,称作递归函数
2.每个递归函数必须有一个终止调用的条件语句,否则陷入永不结束的无穷递归

斐波那契数列

迭代实现

1
2
3
4
5
6
7
8
9
var a=[];
a[0] = 1;
a[1] = 1;
for(var i =2;i<40;i++){
a[i]=a[i-1]+a[i-2];
}
for(var j=0;j<40;j++){
console.log(j,a[j]);
}

递归实现

1
2
3
4
5
6
7
8
9
function fib(n){
if(n<2){
return 1;
}
if(n>1 && n<40){
return fib(n-1)+fib(n-2);
}
}
console.log(fib(4));

n!阶乘递归算法

1
2
3
4
5
6
7
8
9
function fib(n){
if(n>0){
return n*fib(n-1);
}else{
return 1;
}

}
console.log(fib(4));

汉诺塔问题

1
2
3
4
5
6
7
8
9
10
11
function hanoita(n,x,y,z){
if(n==1){
console.log(x+"->"+z);
}else{
hanoita(n-1,x,z,y);
console.log(x+"->"+z);
hanoita(n-1,y,x,z);
}
}

hanoita(3,"x","y",'z');

递归字符串翻转

1
2
3
4
5
6
7
8
9
10
11
12
13
var string = "hello#";
var count = 0;
function print(){
if(string[count]!="#"){
count++;
print();
}
count--;
if(count>-1 && string[count]!="#"){
console.log(string[count]);
}
}
print();

折中查找法递归

代码链接

小结

1.迭代使用循环结构,递归使用选择结构
2.递归能使程序结构更清晰、简洁、容易让人理解,从而减少读懂代码的时间
3.大量的递归会建立函数的副本,会消耗大量时间和内存,而迭代不需要
4.递归函数分为调用和回退阶段,递归的回退顺序是它调用顺序的逆序

My Little World

KMP算法

发表于 2017-02-02

next数组

经推导发现,进行模式匹配时,子串的移位规律与主串内容无关,与子串的内容有关,
因此根据子串的内容,生成基于子串的next数组,用来存放在对应位置如果发生失配,
应该将子串的哪个位置移动到失配位置
1.失配位置的前缀:永远是子串第一位
2.失配位置的后缀:失配位置的前一位
3.失配位置的前后缀相同位数:
从第一位开始的n位和从后缀开始倒数的n位相同,但前缀连续长度最长不能包含后缀那一位,
后缀也不能包含前缀,重叠也没关系,就说失配位置的前缀和后缀有n位相同
例:
ababc
若在倒数第二位的b位置(位置4)失配,则位置4的前缀是位置1的a,后缀是位置3的a,
从位置1和位置3开始,二者只有一位相同,则前后缀有1为相同,
若在最后一位位置5失配,前缀a虽然和后缀b不相同,但前缀连续两位ab和后缀连续两位ab相同
则c的前后缀有两位相同
ssssb
若在b位置失配,前缀连续sss,后缀连续sss,虽然重叠位置2和位置3的s,但前后缀相同位数为3
4.next数组值
失配位置的next数组值 = 失配位置的前后缀相同位数 + 1
特殊情况:子串位置1的next数组值为0,位置2的next数组值为1
例:

T: a b a b a a a b a
下标: 1 2 3 4 5 6 7 8 9
next: 0 1 1 2 3 4 2 2 3

next数组获取代码实现

i后缀 1 2 。 3 4 5 6 7 。 8 9
j前缀 0 1 0 1 2 3 4 2 1 2 3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var string = "9ababaaaba"; //第一位存放字符串长度
function getnext(T){
var next=[];
next[0]=T.length-1;
var i = 1;## 前缀
var j = 0;## 后缀
next[1] = 0;
while(i<T[0]){
if(j==0 || T[i] == T[j]){// 子串自己匹配自己
i++;
j++;
next[i]=j;
}else{
j = next[j]; // 自己匹配发生失配,则视前缀为子串,后缀为主串,将前缀回溯
}
}
console.log(next);
}
getnext(string);

KMP算法

代码链接

My Little World

队列

发表于 2017-02-02

队列

1.先进先出的线性表,有顺序表和链表
2.只允许在一段插入,另一端删除

队列的链式存储结构

和栈相反,队列常用链表实现

1
2
3
4
5
6
7
8
typedef sruct QNode{
ElemType data;
struct QNode *next;
}QNode,*QueuePrt;
typedef struct {
QueuePrt front; ##队头指针指向链队列的头结点(头结点不是必要的)
QueuePrt rear; ##队尾指针指向终端结点,空队列时,front,rear都指向头结点
}LinkQueue;

queue1
queue2

入队列

queue3

1
2
3
4
5
6
7
8
9
10
11
InsertQueue(LinkQueue *q,ElemType e){
QueuePrt p;
p = (QueuePtr)malloc(sizeof(QNode));
if(p==NULL){
exit(0);
}
p->data = e;
p->next = NULL;
q->rear->next = p;
q->rear = p;
}

出队列

queue5
queue6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
DeleteQueue(LinkQueue *q,ElemType e){
QueuePrt p;
if(q->front ==q->rear)
{
retrun;
}
p=q->front->next;
*e=p->data;
q->front->next = p->next;
if(q->rear ==p){
q->rear = q->front;
}
free(p);
}

销毁一个队列

由于链队列建立在内存的动态区,因此当一个队列
不在有用时,应当及时销毁掉,以免过多占用内存空间

1
2
3
4
5
6
7
DestroyQueue(LinkQueue *q){
while(q->front){
q->rear = q->front->next;
free(q->front):
q->front = q->rear;
}
}

简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var list = [];
for(var i=0;i<5;i++){
list.push({
next:i+1
})
}
list[4].next = null;
console.log(list);
//入队列
var length = list.length;
list.push({
next:null
})
list[length-1].next=length;
console.log(list);
//出队列
list.splice(0,1);
console.log(list);
//清空
list=[];

My Little World

栈

发表于 2017-02-02

栈

1.特殊线性表,所以也分为顺序存储和链式存储结构
2.表尾称为栈尾,表头称为栈底
3.元素必须后进先出;所有操作只能在表尾进行
4.插入操作叫做进栈/入栈/压栈,删除操作叫出栈/弹栈
5.最开始栈中不含有任何数据,叫空栈,此时栈顶就是栈底,
然后数据从栈顶进入,栈顶栈底分离,整个栈的当前容量变大,
数据出栈时从栈顶弹出,栈顶下移,整个栈的当前容量变小

1
2
3
4
5
6
7
栈的顺序存储结构
typedef struct
{
ElemType *base; ##指向栈底的指针变量
ElemType *top; ##指向栈顶的指针变量
int stackSize; ##栈当前可使用的最大容量
}sqStack;

入栈操作

每次向栈中压入一个数据,top指针+1,直到栈满为止

出栈操作

在栈顶取数,栈顶指针随之下移,当前容量-1,

JS数组push和pop方法对数组处理

二进制转10进制
主要思想,每次pop数组最后一项,即二进制的位数依次增长,顺序i正好为指数

1
2
3
4
5
6
7
8
var list = [1,1,0,1,0,1,0,1];
var sum = 0;
var length = list.length;
for(var i = 0;i<length;i++){
var pop = list.pop();
sum+= pop*Math.pow(2,i);
}
console.log(sum);

二进制转8进制
主要思想,三位一组生成10进制,最后十进制按位数相加

1
2
3
4
5
6
7
8
9
10
11
12
13
var list = [1,1,0,1,0,1,0,1];
var hex = 0;
var length = list.length;
for(var i=0;i<length/3+1;i++){
var sum = 0;
for(var j = 0;j<3;j++){
if(list.length>0){
sum+=list.pop()*Math.pow(2,j);
}
}
hex +=sum*Math.pow(10,i);
}
console.log(hex);

二进制转16进制
注意 >9时,转换成字母,pop,进行反序链接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var list = [1,1,0,1,0,1,0,1];
var hex = [];
var length = list.length;
for(var i=0;i<length/4+1;i++){
var sum = 0;
if(list.length>0){
for(var j = 0;j<4;j++){
if(list.length>0){
sum+=list.pop()*Math.pow(2,j);
}
}
if (sum >-1&&sum<10) {
hex.push(String.fromCharCode(sum+48));
}
if(sum >9 && sum <16){
hex.push(String.fromCharCode(sum+55));
}
}
}
var str = "";
for(var l = hex.length-1;l>-1;l--){
str+=hex[l];
}
console.log(str);

My Little World

逆波兰表达式/后缀表达式

发表于 2017-02-02

栈的链式存储结构

栈的链式存储结构

stack2

1
2
3
4
5
6
7
8
typedef struct StackNode{
ElemType data; ##存放栈的数据
struct StackNode *next;
}StackNode,*LinkStackPtr;
typedef struct LinkStack{
LinkStackPrt top; ##top指针
int count; ##栈元素计数器
}

栈链的入栈操作

假设元素值e的新结点是s,top为栈顶指针

1
2
3
4
5
6
7
8
Status Push(LinkStack *s,ElemType e){
LinkStackPtr p=(LinkStackPtr)malloc(sizeof(StackNode));
p->data = e;
p->next = s->top;
s->top = p;
s->count++;
return OK;
}

栈的出栈操作

假设变量p用来存储要删除的栈顶结点,将栈顶指针下移一位,最后释放p

1
2
3
4
5
6
7
8
9
10
11
12
Status Pop(LinkStack *s,ElemType e){
LinkStackPtr p;
if(StackEmpty(*s)){
return ERROR;
}
*e=s->top->data;
p=s->top;
s->top = s->top->next;
free(p);
s->count--;
return OK;
}

逆波兰表达式/后缀表达式

正常表达式–>后缀表达式
(1-2)x(4+5)–> 1 2 - 4 5 + x
1.计算后缀表达式
主要思想是判断字符是否为运算符,若为数字,则入栈,为运算符则连续出栈两次进行运算,再将运算结果入栈

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var list =[1,2,3,4,'-','*','+']
var stack = [];
for(var i = 0;i<list.length;i++){
if(!isNaN(list[i])){
stack.push(list[i]);
}else{
var a = stack.pop();
var b = stack.pop();
if(list[i] =="+"){
stack.push(b+a);
}else if(list[i] =="-"){
stack.push(b-a);
}else if(list[i] =="*"){
stack.push(b*a);
}else if(list[i] =="/"){
stack.push(b/a);
}
}
}
console.log(stack);

2.计算表达式转后缀表达式
主要思路
1,表达式中参与运算的数字、运算符以及小括号分割,形成待处理数组
2,循环判断
A.若字符为数字,入栈2,
B.若字符为“+”、“-”,分情况讨论
(1)此时栈1为空,入栈;
(2)栈1不为空,将“(”左括号以上的符号从栈1 pop到栈2,“(”留 在栈1,处理完后,将“+”、“-”入栈1;
C若字符为“)”,将“(”以上符号从栈1 pop到栈2,“(”也pop出来
但不入栈2
D若字符为“/”“*”“(”直接入栈2
E其他情况,非法字符,抛出异常
3.将栈1元素pop到栈2;
栈2即后缀表达式
代码链接

My Little World

双向循环链表

发表于 2017-02-02

结构

1
2
3
4
5
typedef struct DualNode{
ElemType data;
struct DualNode *prior;//前驱结点
struct DualNode *next;//后继结点
}DualNode,*DuLinkList;

doublylinklist1
doublylinklist2
双向链表插入
doublylinklist3
s->next = p;
s->prior = p->prior;
p->prior->next = s;
p->prior = s;
双向链表删除
doublylinklist4
p->prior->next = p->next;
p->next ->prior = p->prior;
free(p)
小结
双向链表相对于单链表来说复杂一点,每个结点对了一个prior指针,在进行插入和删除时需要注意;
双向链表可以有效提高算法的时间性能,用空间换取时间

My Little World

拉丁方阵

发表于 2017-02-02

lating1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function Latinsquare(num){
var list=[];
for(var i = 0;i<num;i++){
var pre = 0;
if(i==0){
pre=num;
}else{
pre = i;
}
var nextt = 0;
if(i ==num-1){
nextt = 1;
}else{
nextt = i+2;
}
list.push({
prior:pre,
data:i+1,
next:nextt
})
}
for(var i = 0;i<num;i++){
var string=[];
var p = 1;
for(var j = 0;j<i;j++){
p = list[p-1].next;
}
for(var k = 0;k<num;k++){
string.push(list[p-1].data);
p = list[p-1].next;
}
console.log(string);
}
}
Latinsquare(5);

1…232425…27
YooHannah

YooHannah

264 日志
1 分类
23 标签
RSS
© 2025 YooHannah
由 Hexo 强力驱动
主题 - NexT.Pisces