2024-03-01T16:56:09+00:00 longest substring without repeating charaters 2019-03-22T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/longet_str_without_repaear Longest substring without repeating charaters无重复字符的最长子串

题目

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: “abcabcbb” Output: 3 Explanation: The answer is “abc”, with the length of 3. Example 2:

Input: “bbbbb” Output: 1 Explanation: The answer is “b”, with the length of 1. Example 3:

Input: “pwwkew” Output: 3 Explanation: The answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.

题目理解

给定字符串,找到没有重复的字符的子串,返回符合的子串的最大长度

解题思路1

我首先想到的就是暴力求解:

1.求子串:遍历字符串,对每个字符作为子串的头,用substr(start,length)得到子串,
如果某个子串中出现重复字符,则从下一个字符开始作为子串的头;	
2.判断子串是否有重复字符:遍历子串,O(n^2),这一步可以使用stl容器map或set降低时间复杂度;
3.比较子串长度。

代码

bool repeat(string s) {
    int len = s.size();
    if (len <= 1) return false;
    for (int i = 0; i < len; i++) {
        for (int j = i+1; j < len; j++) {
            if (s[i] == s[j]) return true;
        }
    }
    return false;
}
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.size();
        // cout << len;
        if (len < 1) return 0;
        int count = 1;
        for (int i = 0; i < len; i++) {
            for (int j = 1; j <= len-i; j++) {
                string substr = s.substr(i, j);
                // cout << "i=" << i << substr << endl;
                if (!repeat(substr)) {
                    // cout << j << endl;
                    if (count < j) count = j;
                } else {
                    break;
                }
            }
        }
        return count;
    }
};

改进:使用STL容器

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int len = s.size();
        // cout << len;
        if (len < 1) return 0;
        int count = 1;
        
        set<char> unique;
        for (int i = 0; i < len; i++) {
            unique.clear();
            unique.insert(s[i]);
            
            for (int j = i+1; j < len; j++) {
                if (unique.find(s[j]) != unique.end()) {
                    break;
                } else {
                    unique.insert(s[j]);
                    // cout << "j=" << j << " " << count << endl;
                    count = count > j-i+1 ? count : j-i+1;
                }
                
            }
            // set<char>::iterator it = unique.begin();
            // for (; it != unique.end(); it++) {
            //     cout << *it << " ";
            // }
            // cout << endl;
        }
        return count;
    }
};

解题思路2

建立hash map,用数组记录ascii码表中字符在字符串中最近一次出现的位置,在字符出现的两次位置下标相减就得到了子字符串的长度

代码

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
            // ASCII码表索引,记录对应字符char最近一次出现的位置下标
            int indices[256];
            memset(indices,-1,sizeof(indices));
        
            int strLength = s.size();
            int maxLength = -1; // 已记录的最大长度
            int minindex = 0;   // 上一次搜索无重复的最小下标
            for(int i=0 ; i<strLength; i++){
            		// int(s[i])表示字符在ascii表中的序号
                // cout << indices[int(s[i])] << " " << minindex << endl;
                minindex = max( indices[ int(s[i]) ]+1 , minindex);
                maxLength = max(maxLength, i - minindex);
                // cout << maxLength << endl;
                indices[int(s[i])]=i;
            }
            return maxLength+1;
    }
};

时间复杂度

  时间复杂度 leetcode note
思路1.1 O(n^4) 986 / 987 test cases passed 当字符串长时会发生超时
思路1.2 O(n^2) Runtime: 1164 ms; Memory:271.7 MB  
思路2 O(n) Runtime: 20 ms; Memory:14.5 MB  
]]>
Data Mining期末报告 2018-07-18T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/Data Mining期末报告 Data Mining期末报告

15331356杨婕

分类算法介绍与分析

  • 课堂上所介绍的算法,或者相关研究领域的算法(请引用相关 的参考文献)
  • 分析所用算法理论上的优缺点、时间复杂度、内存需求等

期末项目是一个分类问题,但难点在于样本的数量多,大约有7万个样本,并且特征的维数大,有6812维,对于分类器的训练除了正确率,还存在模型训练的占用内存问题和训练时间复杂度。 所以基于这两点,进行了各种尝试。

1.基于边缘检测的SVM分类算法

  • 参考论文:
  • 原理:
    • 对于大数据的SVM算法,可以采用抽样减少训练样本的方法。
    • 但是减少训练集会影响分类器的性能,在支持向量机中,分类边界是由支持向量决定的,为了保证分类效率,应该保留最有可能成为支持向量的样本。
    • 根据SVM理论,在分类边界附近的样本,成为支持向量的可能性更高,因此通过检测边缘样本训练SVM模型可以保持训练分类器的性能,也能大大减少训练集数量,达到减小训练占用内存和训练时间的问题。
    • 但是仅仅采用边界检测得到的样本不能有效反映原训练集的分布状况,会影响分类器的分类精度,所以通过聚类技术,对原训练集进行聚类得到聚类中心,加入压缩后的训练集。在论文中是使用K-means算法,也可以使用其他聚类算法。
  • 边缘检测算法和聚类算法重构训练集:
    • 确定最近邻数目m
    • 通过边界检测技术,寻找训练集的边界点
      • (1)对于每个样本点,查找其m个最近邻居(使用KNN算法)
      • (2)检查最近邻居的样本类别(label),如果和该样本点属于同一个类别(说明不是边界样本),那么这个样本点将被删除,如果不是同一个类别,则保留该样本点
    • 确定K-means的K值,对整个训练集进行聚类
    • 重构训练集,将边缘样本和聚类中心取并集得到压缩的训练集
  • 论文中模拟实验效果:
    • 利用边缘检测和聚类算法减少样本,重构训练集:

      <img src=’/image/DataMing/边缘检测1.png’ width=50% hegiht=50% align=center />

    • 原始训练集及SVM训练超平面与重构训练集及SVM训练超平面:

      <img src=’/image/DataMing/边缘检测2.png’ width=50% hegiht=50% align=center />

    • 训练准确率及训练时间复杂度对比:

      <img src=’/image/DataMing/边缘检测3.png’ width=50% hegiht=50% align=center />

  • 算法存在的问题:
    • 虽然可以减少大量样本,并且加快训练的速度,但是前期数据处理需要花费大量时间
  • 算法应用:
    • 由于项目中的数据类别有397个,训练一对多分类器也需要训练约400个,在检测边缘时,需要对每个样本点检测,处理时间需要一周多(甚至更长时间),所以实际对训练的内存有减少但时间却增加了。
    • 聚类的K值难以确定(论文中没有说明如何选取,所以应用中对每个类按50个样本取一个聚类中心),对数据重构的效果可能不如论文中的重构效果。
    • 该算法减少大量样本,训练不需要大量的内存,但是由于按照预处理时间太长,最终没有运行出结果。
    • 使用其他方法查找边缘
      • 使用每个类聚类的中心,查找每个类中距离每个中心最远的10个样本作为边缘,从而得到减少样本的训练集,进行SVM训练(使用sk-learn的SVM接口),使用一对多的思想分别训练397个分类器,再分别用不同的分类器进行预测,如果在某个分类器预测为1则标记为该分类器正样本的label。
      • 该算法占用较少的内存,大约4G的内存,训练时间大约为10小时
      • 但是这个算法的准确率非常低,原因可能是聚类的K值不合理,或者查找的边缘样本不足,或者这样查找的样本不是边缘样本。

2.LightGBM

  • 参考文献:
    • LightGBM官方文档http://lightgbm.readthedocs.io/en/latest/Python-API.html
  • 原理:Light GBM是微软的开源项目,是对基础提升算法的改进,对数据和特征进行并行化,提高训练效率;用GOSS对训练样本进行采样,在保持分类性能的基础上加速训练;用EFB对数据降维,在保持分类性能的基础上加速训练。
  • 实现:
    • 训练397个分类器,每个分类器的正样本取该分类器对应标签的所有样本作为正样本,其余每个类取2个样本,大约800个样本作为负样本
      # create dataset for lightgbm
      x_train = df_train_x.values
      y_train = df_train_y.values
      lgb_train = lgb.Dataset(x_train, y_train)
      # specify your configurations as a dict
      params = {
          'boosting_type': 'gbdt',
          'objective': 'binary',
          'metric': 'binary_logloss',
          'num_leaves': 31,
          'learning_rate': 0.05,
          'feature_fraction': 0.9,
          'bagging_fraction': 0.8,
          'bagging_freq': 5,
          'verbose': 1
      }
    
      # train
      print("Start training...")
      gbm = lgb.train(params,
                  lgb_train,
                  num_boost_round=10)
    
    • 用test数据进行预测时,对一个样本按分类器遍历预测,如果某个分类器预测结果为1,则将该样本预测为该分类器的label,如果预测为-1,则读取下一个分类器进行预测。
    • 实验结果:
      • 训练时间非常短,预处理大约需要20分钟,训练397个分类器大约花了一个半小时
      • 大部分样本分类为2,kaggle上准确率只有0.04
      • 猜想原因:由于分开训练分类器进行预测,使得分类非常依赖于前几个分类器,比如实验中label为2的分类器效果不好,使得大量样本分为2
      • 如果用Light GBM的多分类直接对所有样本进行训练可能效果会不错,但是需要占用大量内存,所以没有进行实验,而是选择其他算法进行实验

3.多层感知机MLPClassifier

  • 参考文献:
    • SK-learn官方文档:http://scikit-learn.org/dev/modules/neural_networks_supervised.html#classification
  • 原理:多层感知机(MLP,Multilayer Perceptron)也叫人工神经网络(ANN,Artificial Neural Network),除了输入输出层,它中间可以有多个隐层,最简单的MLP只含一个隐层,即三层的结构,如下图:

    <img src=’/image/DataMing/mlp1.jpeg’ width=50% hegiht=50% align=center />

    多层感知机层与层之间是全连接的,假设输入层用向量X表示,则隐藏层的输出就是f(W1X+b1),W1是权重(也叫连接系数),b1是偏置,函数f 可以是常用的sigmoid函数或者tanh函数。隐藏层到输出层可以看成是一个多类别的逻辑回归,也即softmax回归,所以输出层的输出就是softmax(W2X1+b2),X1表示隐藏层的输出f(W1X+b1)。解决最优化问题是用梯度下降法(SGD):首先随机初始化所有参数,然后迭代地训练,不断地计算梯度和更新参数,直到满足某个条件为止(比如误差足够小、迭代次数足够多时)。

  • 实现:
    • 使用python的sk-learn机器学习库的MLPClassifier接口,直接调用,修改隐藏层的层数及神经元个数进行调参
    • 使用全部的训练集,对特征集进行归一化,然后传入MLPClassifier函数
    • 由于使用全部数据集,并且没有降维,所以读取csv格式数据需要很长时间,48分钟左右,大约1个小时,归一化大约需要10分钟,并且占用大约10G的内存
    • 使用2个隐藏层,各100个神经元
        clf = MLPClassifier(solver='adam', alpha=1e-5,hidden_layer_sizes=(100,100), random_state=1,verbose=True,max_iter=100)
      

    <img src=’/image/DataMing/mlp2.png’ width=50% hegiht=50% align=center />

      经过22个迭代,模型收敛,损失函数loss=0.22404616,模型训练大约6分钟,预测准确率为0.17229   * 使用2个隐藏层,各500个神经元   ```   clf = MLPClassifier(solver='adam', alpha=1e-5,hidden_layer_sizes=(500,500), random_state=1,verbose=True,max_iter=100)   ```   <img src='/image/DataMing/mlp3.png' width=50% hegiht=50% align=center />
    
      经过9个迭代,模型收敛,损失函数loss=0.33467016,模型训练大约9分钟,预测准确率为0.21360
    

4.SGDClassifier

  • 参考文献:
    • SK-learn官方文档:http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDClassifier.html
  • 原理:SGDClassifier是一个用随机梯度下降算法训练的线性分类器的集合。默认情况下是一个线性(软间隔)支持向量机分类器,用梯度下降算法来最小化支持向量机的合页损失函数。
  • 实现:
    • 使用python的sk-learn机器学习库的linear_model.SGDClassifier接口,直接调用
    • 使用全部的训练集,对特征集进行归一化,然后传入linear_model.SGDClassifier函数
    • 由于使用全部数据集,并且没有降维,所以读取csv格式数据需要很长时间,48分钟左右,大约1个小时,归一化大约需要10分钟,并且占用大约10G的内存
    • 训练时间大约为34分钟,准确率为0.25978

实验结果分析

  • 对比不同算法的分类效果和计算复杂度
使用算法 运行时间 分类准确率
基于边缘检测的SVM算法:KNN边缘检测 预计大于2周 没有运行出来
基于边缘检测的SVM算法:利用聚类中心查找边缘 约20小时 0.00251
LightGBM 约2小时 0.04860
MLPClassifier:2个隐藏层,各100个神经元 读取处理数据约1小时,训练约6分钟 0.17229
MLPClassifier:2个隐藏层,各500个神经元 读取处理数据约1小时,训练约9分钟 0.21360
SGDClassifier 读取处理数据约1小时,训练约34分钟 0.25978
]]>
系统分析与设计HW11 2018-06-30T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW11 系统分析与设计HW11

使用 ECB 实现 make reservation 用例的详细设计

  • 用例图

reservation_usecase

  • 识别出来的BCE类
    • Bounary 边界类:
      • searchHotel
      • chooseHotel
      • makeReservation
    • Control 控制类:
      • reserveHotelController订酒店控制类
    • Entity 实体类:
      • traveler旅客(用户)
      • reservation订单类
      • payment支付类
      • hotel酒店类
  • 顺序图

reservation_sequence

  • 类图

reservation_class

将逻辑设计类图映射到实际项目框架的包图。用树形结构表述实现的包和类

reservation_map

]]>
系统分析与设计Final Report 2018-06-30T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-FinalReport 系统分析与设计 Final Report

课程学习自我总结

这个课程让我了解到一个项目团队开发的过程。由于大一大二基本是个人开发的小程序,所以也不需要考虑用户需求、交互逻辑等等的问题,这个团队作业需要从前期设计、文档编写到代码实现、用例测试,在这个完整的开发过程中认识到一个项目开发工作前期文档编写完整和正确的重要性,特别是用例设计和逻辑设计,便于协同开发。而项目管理方面,协同开发工具起了重要作用,包括GitHub和协同工作文档石墨等等。最后要感谢两位大佬lonelyhopemukae1997实力carry。

PSP 2.1 统计表

PSP2.1 Time (h)
计划 8
·估计这个任务需要多少时间 8
开发 182
·分析需求 24
·生成设计文档 20
·设计复审 (和同事审核设计文档) 8
·代码规范 (为目前的开发制定合适的规范) 2
·具体设计 8
·具体编码 36
·代码复审 4
·测试(包括自我测试,修改代码,提交修改) 12
测试报告 6
事后总结, 并提出过程改进计划 8
合计 190

个人分支的GIT统计报告

  • dashboard

dashboard_git

  • clientcode

clientcode_git

工作清单

  • 完成原型设计:项目原型设计
  • 部分前端组件实现
  • 测试并修复多个bug:
    • 关注者页面(follow)和粉丝页面(follower)关注状态问题和关注取关的按钮动态变化问题
    • 首页(home)和查看用户的starpick的评论与对应starpick不匹配问题
    • 点赞pick和踩diss显示错误问题

个人的技术类、项目管理类博客清单

原型设计工具-Mockplus的使用

]]>
系统分析与设计HW10 2018-06-08T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW10 系统分析与设计HW10
  1. 描述软件架构与框架之间的区别与联系
    • 软件架构: 软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段,这些抽象组件被细化为实际的组件,比如具体某个类或者对象。在面向对象领域中,组件之间的连接通常用接口来实现。
    • 框架: 软件框架(Software framework),软件框架其实就是将代码放到一个我们看不到的容器中,规定架构。当我们使用的时候直接调用。其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。
    • 区别:
      • 软件框架是一个软件产品,而软件架构不是软件产品;
      • 软件架构所呈现的是一个设计规约,而软件框架是程序代码;
      • 软件架构的首要目的大多是指导一个软件系统的实施和开发,而框架的首要目的是为了复用;
  2. 以你的项目为案例
    • 绘制三层架构模型图,细致到分区

    • 结合你程序的结构,从程序员角度说明三层架构给开发者带来的便利
      • 开发人员可以只关注整个结构中的其中某一层;
      • 可以很容易的用新的实现来替换原有层次的实现;
      • 可以降低层与层之间的依赖;
      • 有利于标准化;
      • 利于各层逻辑的复用;
      • 结构更加的明确;
      • 在后期维护的时候,极大地降低了维护成本和维护时间。
  3. 研究 VUE 与 Flux 状态管理的异同
  • 关于Flux状态管理
    • 状态集管理框架,由Facebook创建,专门用来构建前端框架结构的框架,便于维护,用于安全考虑,它分为4层:view视图层,action,dispatcher派发层,store仓库层
    • redux是flux中的一个实现(不是所有的项目都适合redux)

    redux的流程:view -> action -> store -> reducer(返回)-> store -> view   

  • 关于VUE状态管理
    • Vue 提供 vuex:Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
    • vuex多个组件调用一个状态,将原来组建与组件之间的状态传递改成组件与仓库之间的传递
    • vuex核心:
      • state:存放多个组件共享的状态(数据)
      • mutations:存放更改state里状态的方法,用于变更状态,是唯一一个更改状态的属性
      • getters:将state中某个状态进行过滤,然后获取新的状态,类似于vue中的computed
      • actions:用于调用事件动作,并传递给mutation
      • modules:主要用来拆分state

    vueComnent -> (dispatch)Action -> (commit) -> Mutations ->(mutate)State -> (render)VueComponent

  • Flux与VUE状态管理的异:
    • 两者的数据流的流程不同。Flux的流程是:View发起Action->Action传递到Dispatcher->Dispatcher将通知Store->Store的状态改变通知View进行改变,而VUE的流程是:用户组件的输入触发action调用->actions通过commit一个mutation对store实例的状态进行修改->store实例状态变化反过来又通过getters被组件获知。
    • Flux不区分同步和异步更改,而Vuex区分, commit时同步更新, action是异步更新。
  • Flux与VUE状态管理的同:
    • Flux最早提出作为对传统前端MVC的一种改进,vuex是redux的基础上进行改变,对仓库的管理更加明确。
    • 都通过store来存储状态。
]]>
Three.js学习笔记(一) 2018-05-14T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/LearnThree.js Three.js 学习笔记(一)

一. 准备Three.js

下载three.js:https://github.com/mrdoob/three.js

在html文件中引用文件three.js

// 注意文件地址
<script src="/Users/admin/Documents/opengl/three.js-dev/build/three.js"></script>

二. 三大组建

在three.js中,要渲染物体到网页,需要三个组建:场景(scene),相机(camera)和渲染器(renderer)

场景scene

在three.js中,场景就只有一种,用THREE.Scene表示,场景时所有物体的容器。 创建一个场景:

scene = new THREE.Scene();

相机camera

相机决定了场景中那个角度的景色会显示出来。相机就像人的眼睛一样,人站在不同位置,抬头或者低头都能够看到不同的景色。

场景只有一种,但是相机却又很多种。和现实中一样,不同的相机确定了呈相的各个方面。比如有的相机适合人像,有的相机适合风景,专业的摄影师根据实际用途不一样,选择不同的相机。

对程序员来说,只要设置不同的相机参数,就能够让相机产生不一样的效果。 在Three.js中有多种相机,最常用的是透视相机(THREE.PerspectiveCamera),创建一个透视相机:

var camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );

渲染器renderer

渲染器决定了渲染的结果应该画在页面的什么元素上面,并且以怎样的方式来绘制。定义了一个WebRenderer渲染器,代码如下所示:

// antialias平滑
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

三. 渲染物体

添加物体到场景中

// 创建一个立方体几何体
// 函数原型:CubeGeometry(width, height, depth, segmentsWidth, segmentsHeight, segmentsDepth, materials, sides)
var geometry = new THREE.CubeGeometry(1,1,1); 
// 设置立方体的材质和颜色
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material); 
// 添加立方体到已创建的场景中
scene.add(cube);

// 创建一个盒子
// 效果为 https://jsfiddle.net/f2Lommf5/
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

渲染

渲染函数的原型如下:

render( scene, camera, renderTarget, forceClear )

各个参数的意义是:

  • scene:前面定义的场景

  • camera:前面定义的相机

  • renderTarget:渲染的目标,默认是渲染到前面定义的render变量中

  • forceClear:每次绘制之前都将画布的内容给清除,即使自动清除标志autoClear为false,也会清除。

渲染循环

渲染有两种方式:实时渲染和离线渲染

离线渲染:是事先渲染好一帧一帧的图片,然后再把图片拼接成电影的。这就是离线渲染。如果不事先处理好一帧一帧的图片,那么电影播放得会很卡。CPU和GPU根本没有能力在播放的时候渲染出这种高质量的图片。

实时渲染:就是需要不停的对画面进行渲染,即使画面中什么也没有改变,也需要重新渲染。

下面就是一个渲染循环:

function render() {
	cube.rotation.x += 0.1;
	cube.rotation.y += 0.1;
	renderer.render(scene, camera);
	requestAnimationFrame(render);
}

其中一个重要的函数是requestAnimationFrame,这个函数就是让浏览器去执行一次参数中的函数,这样通过上面render中调用requestAnimationFrame()函数,requestAnimationFrame()函数又让render()再执行一次,就形成了我们通常所说的游戏循环了。

requestAnimationFrame()函数实际上可以放到render函数中的任何一行,而不是说非要放到第一行,放在第一行,render中其他的代码就不能执行,这是错误的,requestAnimationFrame函数并不是一个return语句,并没有退出render函数的功能。 requestAnimationFrame函数表示下一帧将执行render函数,不是马上执行render函数的意思。

]]>
系统分析与设计HW9 2018-05-10T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW9 系统分析与设计HW9

建模练习

  • 练习文档编写:
    • 选择一个你喜欢的移动APP或其中某业务
    • 参考Asg_RH文档格式编写软件描述
    • 文档要包含一个业务的完整过程
  • 建模要求包括用例图,xx业务或用例的活动图,xx领域模型,xx对象的状态图,xx场景的系统顺序图与操作协议
  • 建模者答案

1.文档编写

团队文档地址:GitHub_XX建模练习

选择移动APP的某个业务:虾米音乐搜索并添加歌曲到歌单的业务

Screenshot 1 Screenshot 1

Screenshot 1 首页,要求用户user在搜索栏输入歌曲关联词,比如歌曲名字,歌唱者名字等。搜索按钮允许向系统提交请求,在搜索结果中显示与关联词相关的结果。

Screenshot 2 Screenshot 2

Screenshot 2 显示了点击搜索栏的界面,用户可以输入想要搜索的相关词。

Screenshot 3 Screenshot 3

Screenshot 3 显示了搜索结果(正确搜索的结果)界面,默认显示歌曲检索结果,可切换到其他检索结果(专辑,艺人,歌单,mv,用户)。(以检索歌唱者名字为例)

  • 你可能感兴趣的结果:正确检索的结果是歌手的名字及其简介显示在第一个检索结果。
  • 已为你找到x首相关歌曲:显示搜索歌手的歌曲,向下滑动可以查看更多结果。
  • 切换检索结果:
    • 专辑:显示歌唱者所演唱的专辑
    • 艺人:显示歌唱者的艺人词条,点击可以查看艺人的详情
    • 歌单:显示含有歌唱者名字的歌曲的歌单
    • MV:显示艺人相关的MV
    • 用户:显示用户名含有所检索关键词的用户
  • 点击任一搜索结果的歌曲右侧的三点可以对歌曲进行添加到歌单操作,如Screenshot 5所示。

如果没有相关的结果,则显示没有搜索到任何内容,如Screenshot 4所示,选择取消则回到Screenshot 1的界面,重新输入关联词则再次搜索。

Screenshot 4 Screenshot 4

Screenshot 5 Screenshot 5

Screenshot 5 显示了对所选歌曲可以进行的操作,点击加到歌单,自动跳转到Screenshot 6

Screenshot 6 Screenshot 6

Screenshot 7 Screenshot 7

Screenshot 6 显示了用户已创建的歌单列表,点击+新建歌单,则如Screenshot 7所示,要求用户输入歌单名称,或点击已存在的歌单,系统显示添加成功,自动跳转到Screenshot 3,完成搜索并添加歌曲到歌单的业务。如果用户没有登陆,则只显示+新建歌单按钮,点击则跳转到Screenshot 8要求用户登陆。

Screenshot 8 Screenshot 8

Screenshot 8 显示用户登陆界面,要求用户输入邮箱或手机号及密码,进行登陆操作,登陆成功则跳转到Screenshot 6 ,用户可选择目标歌单进行添加。

2.个人建模练习

选择其他团队的建模练习文档: 淘宝外卖点餐系统

业务:淘宝外卖点餐系统

1.用例图

订餐系统的用例图:

订餐系统的用例图

2.活动图

订餐用例的活动图:

订餐系统的活动图

3.领域模型

订餐系统的领域模型:

订餐系统的领域模型

4.状态图

订单对象的状态图:

订餐系统的状态图

5.系统顺序图与操作协议

完成订单生成及支付的主成功场景:

订餐系统的系统顺序图

]]>
系统分析与设计HW8 2018-05-06T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW8 系统分析与设计HW8

1)使用 UML State Model

  • 建模对象: 参考 Asg_RH 文档, 对 Reservation/Order 对象建模。
  • 建模要求: 参考练习不能提供足够信息帮助你对订单对象建模,请参考现在 定旅馆 的旅游网站,尽可能分析围绕订单发生的各种情况,直到订单通过销售事件(柜台销售)结束订单。

   

2)研究淘宝退货流程活动图,对退货业务对象状态建模

]]>
系统分析与设计HW7 2018-04-29T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW7 系统分析与设计HW7

1、 领域建模

a. 阅读 Asg_RH 文档,按用例构建领域模型。 按 Task2 要求,请使用工具 UMLet,截图格式务必是 png 并控制尺寸 说明:请不要受 PCMEF 层次结构影响。你需要识别实体(E)和 中介实体(M,也称状态实体) 在单页面应用(如 vue)中,E 一般与数据库构建有关, M 一般与 store 模式 有关 在 java web 应用中,E 一般与数据库构建有关, M 一般与 session 有关

b. 数据库建模(E-R 模型)

  • 按 Task 3 要求,给出系统的 E-R 模型(数据逻辑模型)
  • 建模工具 PowerDesigner(简称PD) 或开源工具 OpenSystemArchitect
  • 不负责的链接 http://www.cnblogs.com/mcgrady/archive/2013/05/25/3098588.html

  • 导出 Mysql 物理数据库的脚本
-- MySQL Script generated by MySQL Workbench
-- Mon April  29 14:04:29 2018
-- Model: New Model    Version: 1.0
-- MySQL Workbench Forward Engineering

SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------

-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 ;
USE `mydb` ;

-- -----------------------------------------------------
-- Table `mydb`.`room`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`room` (
  `roomID` INT NOT NULL,
  `roomType` VARCHAR(45) NULL,
  `hotelName` VARCHAR(45) NULL,
  PRIMARY KEY (`roomID`))
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`hotel`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`hotel` (
  `hotelName` VARCHAR(45) NOT NULL,
  `city` VARCHAR(45) NULL,
  `town` VARCHAR(45) NULL,
  `room_roomID` INT NOT NULL,
  PRIMARY KEY (`hotelName`, `room_roomID`),
  INDEX `fk_hotel_room_idx` (`room_roomID` ASC),
  CONSTRAINT `fk_hotel_room`
    FOREIGN KEY (`room_roomID`)
    REFERENCES `mydb`.`room` (`roomID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`reservation`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`reservation` (
  `reservationID` INT NOT NULL,
  `roomType` VARCHAR(45) NULL,
  `checkinDate` DATE NULL,
  `checkoutDate` DATE NULL,
  `price` FLOAT NULL,
  `customerName` VARCHAR(45) NULL,
  `hotel_hotelName` VARCHAR(45) NOT NULL,
  `hotel_room_roomID` INT NOT NULL,
  PRIMARY KEY (`reservationID`, `hotel_hotelName`, `hotel_room_roomID`),
  INDEX `fk_reservation_hotel1_idx` (`hotel_hotelName` ASC, `hotel_room_roomID` ASC),
  CONSTRAINT `fk_reservation_hotel1`
    FOREIGN KEY (`hotel_hotelName` , `hotel_room_roomID`)
    REFERENCES `mydb`.`hotel` (`hotelName` , `room_roomID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`reservation_busket`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`reservation_busket` (
  `userID` INT NOT NULL,
  `reservationID` INT NOT NULL,
  `reservation_reservationID` INT NOT NULL,
  `reservation_hotel_hotelName` VARCHAR(45) NOT NULL,
  `reservation_hotel_room_roomID` INT NOT NULL,
  PRIMARY KEY (`userID`, `reservation_reservationID`, `reservation_hotel_hotelName`, `reservation_hotel_room_roomID`),
  INDEX `fk_reservation_busket_reservation1_idx` (`reservation_reservationID` ASC, `reservation_hotel_hotelName` ASC, `reservation_hotel_room_roomID` ASC),
  CONSTRAINT `fk_reservation_busket_reservation1`
    FOREIGN KEY (`reservation_reservationID` , `reservation_hotel_hotelName` , `reservation_hotel_room_roomID`)
    REFERENCES `mydb`.`reservation` (`reservationID` , `hotel_hotelName` , `hotel_room_roomID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


-- -----------------------------------------------------
-- Table `mydb`.`user`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`user` (
  `userID` INT NOT NULL,
  `userName` VARCHAR(45) NULL,
  `phong` INT NULL,
  `email` VARCHAR(45) NULL,
  `reservation_busket_userID` INT NOT NULL,
  PRIMARY KEY (`userID`, `reservation_busket_userID`),
  INDEX `fk_user_reservation_busket1_idx` (`reservation_busket_userID` ASC),
  CONSTRAINT `fk_user_reservation_busket1`
    FOREIGN KEY (`reservation_busket_userID`)
    REFERENCES `mydb`.`reservation_busket` (`userID`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;


SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
  • 简单叙说 数据库逻辑模型 与 领域模型 的异同
    • 异:领域模型主要是面向需求分析的建模,目的是让业务人员了解需求,而数据库逻辑模型是面向设计的建模,目的是让程序员了解系统的数据逻辑从而设计系统数据结构。
    • 同:都是对系统的结构进行建模,利用图形解释各个类(实体)之间的关系,使工作人员直接地了解系统的设计结构。
]]>
系统分析与设计HW6 2018-04-22T00:00:00+00:00 Joyce Yang http://joyceyj.github.io/SAD-HW6 系统分析与设计HW6

1.用例建模

  • a. 阅读 Asg_RH文档,绘制用例图。 按 Task1要求,请使用工具UMLet,截图格式务必是 png 并控制尺寸

  • b. 选择你熟悉的定旅馆在线服务系统(或移动APP),如绘制用例图。并满足以下要求:
    • 对比 Asg_RH 用例图,请用色彩标注出创新用例或子用例
    • 尽可能识别外部系统,并用色彩标注新的外部系统和服务

    选择马蜂窝网站定旅馆在线服务系统:

    • 用例图:
  • c. 对比两个时代、不同地区产品的用例图,总结在项目早期,发现创新的思路与方法
    • 两个产品的用例图区别并不是很大,但是第二个增加了人们筛选的方法,更加便利,增加了查看其它用户的评价辅助用户做出选择,还有支付方式从银行卡到线上支付等多种方式,总体上增加了用户使用的方便程度。
    • 在项目早期发现创新的思路与方法:

      1.对比多个同类型的产品,记录用户的体验,收集用户意见;

      2.关注最新科技的发展,是否有适合与自己项目结合的技术;

  • d. 请使用 SCRUM 方法,在(任务b)用例图基础上,编制某定旅馆开发的需求(backlog)
           
ID NAME Imp EstHow to Demo Note
1 查找酒店 80 3 用户选择酒店的目标城市,入住/退房时间,入住的成人/儿童的人数,点击搜索 搜索结果按总评价排序,如果没有符合搜索条件的,提醒用户更改相应条件
2 预定酒店 100 6 从搜索结果中选取酒店;可以从结果中根据地图定位将酒店分类,筛选离定位地点最近的酒店;对搜索结果按偏好(评价高低、价格高低)进行排序;按其他筛选条件进行筛选,提供通过关键字模糊搜索酒店;告知用户是否有空房;选择房源(包括其他酒店预订系统);选择房型及其他要求;提供入住者详情;确认下单 注意酒店房间的实时性
3 管理订单 60 2 用户查看自己订单的详情;删除订单 对已支付的订单进行删除需要注意酒店可能要求支付赔偿金
4 支付订单 80 3 用户可以选择不同的在线支付方式进行支付 注意支付的实时性

2.业务建模

  • a. 在(任务b)基础上,用活动图建模找酒店用例。简述利用流程图发现子用例的方法。
  • b. 选择你身边的银行 ATM,用活动图描绘取款业务流程
  • c. 查找淘宝退货业务官方文档,使用多泳道图,表达客户、淘宝网、淘宝商家服务系统、商家等用户和系统协同完成退货业务的过程。分析客户要完成退货业务,在淘宝网上需要实现哪些系统用例
    • 淘宝退货业务流程: https://world.taobao.com/helper/knowledge.htm?kid=6534402

    • 客户要完成退货业务,在淘宝网上需要实现的系统用例有:提交退款申请、提交退货退款申请、更改订单状态、退款、超时自动关闭订单。

3.用例文本编写

在大作业基础上,分析三种用例文本的优点和缺点

  • full use case
    • 优点:详细、深入地描述系统的需求,提供了尽可能详尽的信息
    • 缺点:内容冗长;编写花费时间长
  • casual use case
    • 优点:能相对简洁的说明系统的功能,提供部分信息
    • 缺点:不够详细
  • brief use case
    • 优点:简短,能够很快了解系统的大概功能/需求,编写花费时间短
    • 缺点:只能对需求有粗略的了解
]]>