Quantcast
Channel: CSDN博客推荐文章
Viewing all 35570 articles
Browse latest View live

【蓝桥杯】【等额本金】

$
0
0

题目
小明从银行贷款3万元。约定分24个月,以等额本金方式还款。
这种还款方式就是把贷款额度等分到24个月。
每个月除了要还固定的本金外,还要还贷款余额在一个月中产生的利息。
假设月利率是:0.005,即:千分之五。那么,
第一个月,小明要还本金 1250, 还要还利息:30000 * 0.005,总计 1400
第二个月,本金仍然要还 1250, 但利息为:(30000-1250) * 0.005 总计 1393.75
请问:小明在第15个月,应该还款多少(本金和利息的总和)?
请把答案金额四舍五入后,保留两位小数。注意:32.5,一定要写为:32.50
通过浏览器提交答案,这是一个含有小数点和两位小数的浮点数字。
不要写多余内容(例如:多写了“元”或添加说明文字)

分析
送分题,稍微熟悉bigdecimal的API即可。

源码

    public static void main(String[] args) {
        BigDecimal bd = new BigDecimal(30000-1250*14).multiply(new BigDecimal(0.005));
        //2是小数点后面的精度,ROUND_HALF_UP是四舍五入
        BigDecimal bd2 = bd.setScale(2, BigDecimal.ROUND_HALF_UP).add(new BigDecimal(1250));
        System.out.println(bd2.toPlainString());
    }

结果
1312.50

作者:bear_huangzhen 发表于2017/11/20 14:52:47 原文链接
阅读:58 评论:0 查看评论

电脑硬件知识入门之内存篇

$
0
0

内存相信很多朋友都不会陌生,一般电脑内存越大越好。内存作为电脑必不可少的硬件之一,在装机或者给电脑升级的时候,也需要选择适合自己的内存。那么如何选择电脑内存?今天我们简单来聊聊内存小知识以及选购、使用常见问题等相关知识。


内存是什么

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,因此内存的性能对计算机的影响非常大。内存也被称为内存储器,其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来,内存的运行也决定了计算机的稳定运行。 内存是由内存芯片、电路板、金手指等部分组成的。

内存小知识

电脑内存分为一代、二代、三代和四代....(台式机/笔记本),我们通常所说的几代内存,都是根据内存频率来划分的,具体如下:

DDR是一代内存频率为:DDR266、DDR333、DDR533、DDR667、DDR800;
DDR2是二代代内存频率为:DDR II 533、DDR II 667、DDR II 800;
DDR3是三代内存频率为:DDR III 1066、DDR III 1333、DDR III 1600、DDR III 1866、DDR III 2133;
DDR4是四代内存频率为:DDR IIII 2133、DR IIII 2400、DR IIII 3000、DR IIII 3200。

另外值得一提的是,不同代内存工作电压也是不同的,比如最新的DDR4内存工作电压为1.2V,而DDR3为1.5V,这意味着DDR4内存功耗更低。


目前,近几年的电脑用的都是DDR3内存,而从去年Intel推出的七大CPU和AMD锐龙Ryzen处理器开始,全面支持的是新一代DDR4内存。也就是早一两年的电脑,基本用的是DDR3内存,从今年开始的新平台,开始普及新一代DDR4内存。

内存常见故障有哪些?




两条4G内存和一条8G内存是否能开启双通道?



答案是可以的,将两个4G内存插入同一个通道的两个插槽中,8G独占另一个通道就可以,这算是比较省钱的升级方法了。


DDR3和DDR4可以混用么?



确实有主板同时提供了两代内存插槽,但是都专门强调了,两代内存不可以同时使用。


不同频率的内存组建双通道能成功么?



答案是可以的,一般来说主板会自动将高频内存的频率拉低到低频内存的水平,不过相比较双通道带来的性能翻倍,损失的那一点频率反而不是那么重要。


插入A1和B2接口能组成双通道么?



大多数主板是可以的,但是也不排除有例外,之前笔者在测试的时候曾遇到过插了D1 C1 A2 B2开机被BIOS提示不能使用的情况。


笔记本上的低电压内存(如DDR3L 1.35V)和标压内存(DDR3 1.5V)能同时使用组建双通道吗?



答案是可以的,不过不推荐这样做,笔者之前这样用了很长时间,偶尔会出现死机的情况,不确定是不是内存造成的。




作者:shaoyezhangliwei 发表于2017/11/20 14:53:10 原文链接
阅读:71 评论:0 查看评论

LeetCode--Symmetric Tree

$
0
0

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

    1
   / \
  2   2
 / \ / \
3  4 4  3

But the following [1,2,2,null,3,null,3] is not:

    1
   / \
  2   2
   \   \
   3    3

Note:
Bonus points if you could solve it both recursively and iteratively.

方法一:递归。每次判断对称的两个节点是否相同,以及递归判断他们对称的子节点是否相同。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if (!root) return true;
        return isSymmetric(root->left,root->right);
    }
    bool isSymmetric(TreeNode* p,TreeNode* q){
        if(!p&&!q) return true;
        if(!p||!q) return false;
        return (p->val==q->val)&&isSymmetric(p->left,q->right)&&isSymmetric(p->right,q->left);
    }
};

方法二:非递归。还是用堆栈,基本思路和上面一样,就是注意子节点都是空节点就跳过继续循环。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool isSymmetric(TreeNode* root) {
        if(!root) return true;
        stack<TreeNode*>s;
        s.push(root->left);
        s.push(root->right);
        while(!s.empty()){
            TreeNode *p=s.top();
            s.pop();
            TreeNode *q=s.top();
            s.pop();
            if(!p&&!q) continue;
            if(!p||!q) return false;
            if(p->val!=q->val) return false;
            s.push(p->left);
            s.push(q->right);
            s.push(p->right);
            s.push(q->left);
        }
        return true;
    }
};
作者:qq_20791919 发表于2017/11/20 15:12:10 原文链接
阅读:57 评论:0 查看评论

第30章 客户/服务器程序设计范式

$
0
0

觉得还是按:1 --> 7 --> 9 的顺序选取服务器模型比较(简单)可取。

作者:gongluck93 发表于2017/11/20 15:16:40 原文链接
阅读:58 评论:0 查看评论

cocos-lua学习笔记(八)帧动画

$
0
0

使用版本是 3.7.1 Release

注意:新版本中废除了playAnimationOnce接口。


帧动画过程:

  1.  加载资源 test.plist 和 test.pvr.czz文件,这个文件是经过TexturePacker生成的
  2.  生成桢数组
  3.  生成动画对象
  4.  将动画对象转化为动作,让节点使用。


local MainScene = class("MainScene", function()
    return display.newScene("MainScene")
end)

function MainScene:ctor()
     self.backgroundLayer = display.newColorLayer(cc.c4f(0,0,0,0))
    self.backgroundLayer:addTo(self)

     local btn = ccui.Button:create("button/aaa_N.png", "", "", 0)
        :pos(display.cx, 100)
        :addTo(self)
        --按钮文字
        btn:setTitleText("按钮")
        --字体颜色
        btn:setTitleColor(cc.c3b(255, 255, 255))
        --按钮的回调函数
        btn:addTouchEventListener(function(sender, eventType)
        if (2== eventType)  then
          
         print("playAnimationOnce")
     
              display.addSpriteFrames("test.plist", "test.pvr.ccz")
                 --生成桢数组
         local frames = display.newFrames("8000_0_0000%d.png", 0, 6)
                 --生成对象动画
         local animation = display.newAnimation(frames, 0.2) 
         --转化为Action对象
                 local animate = cc.Animate:create(animation)
                 --生成精灵对象
         local sprite1 = display.newSprite("#000_0_00000.png")
            :center()
            :addTo(self.backgroundLayer)
                       --动起来
            :runAction(animate)
        end
    end)



end

function MainScene:onEnter()
end

function MainScene:onExit()
      print("onExit")
end

return MainScene



效果如下:





资源下载地址:点这里 


步骤:

  1. 首先创建工程
  2. 下载res文件夹,然后替换进去
  3. 替换主场景mainScene文件
  4. 运行,就可以看到效果了


如何生成plist和stars.pvr.ccz ,我下次在写。

作者:hiwoshixiaoyu 发表于2017/11/20 15:24:38 原文链接
阅读:52 评论:0 查看评论

【比特币】SPV是如何工作的

$
0
0

SPV是如何工作的

SPV, Bloom 过滤器和检查点

这是一篇技术文章,获取比特币的工作知识。

一个完整的节点,比如比特币核心,知道以下几点:

  • 每一个当前正在围绕网络广播事务处理
  • 每一个曾经被送到交易
  • 所有未使用的交易产出(UTXO)

这需要大量的数据被下载,存储和索引。 但是,如果不需要完整的块链,则有一些快捷方式可以减少冗余信息的数量。

简化付款验证(SPV)。

SPV提供了一种方法,可以确定某个特定的事务处在块链中的块中,而不需要整个块链被下载。 它这样做如下:

  • 每个事务都有一个散列
  • 每个块都有一个散列
  • 事务散列和块散列可以使用Merkle树证明来链接。

一个梅克尔树是一种数学模型,其中块是在顶点,所有的交易得到安置在一个树状结构。

一个梅克尔树证明是所有的顶点(块),叶(交易)之间的散列的列表。 梅克尔树证明的一点是,您只需要一小部分的块来证明交易在块中。

因此,当一个钱包说它使用SPV时,它意味着在它相信一个交易之前,它会检查:

  • 有一个默克尔树树证明交易是在一个块
  • 该块本身在块链的主链中

交易是“好”,将被添加到钱包。

Bloom过滤器和单一HD帐户支持

很多人都问我们,为什么我们只支持HD帐户(即在正常的说法帐户1)。

主要原因是由于我们如何从比特币核心节点获得我们的交易。 我们使用一种称为布隆过滤的技术。 我们不要求直接交易,而是我们给比特币核心节点,我们知道会匹配所有我们感兴趣的(加上一些误报把任何间谍失去了线索一点点)交易的过滤器。

仅支持一个帐户就意味着为主地址和更改地址的地址数量不断增加创建过滤器。 这开始为“数百”,随着钱包的使用,将变成“数千”。

将其扩展到支持任意数量的帐户意味着创建匹配的过滤器:

账户数量x(主要地址+更改地址)

因此,我们必须过滤以匹配更多的地址(我们认为),我们几乎可以获得完整的块。 这使得我们至少像比特币核心节点一样慢,而且我们上传非常宽泛的过滤器的速度更慢。

我们认为这样做太慢而无用,所以我们将使用限制在一个账户中。

我们没有UTXO集

我们无法访问使用Bitcoinj设置的未使用交易输出(UTXO),因此我们无法直接查看。 只有在其后端具有完整块存储的实现(可直接查询)才能使用UTXO集,这意味着要下载整个块链。

Bitcoinj只会讲比特币网络协议,不支持“给我所有的UTXO这个地址”等功能。

检查点

为了减少需要下载的块的数量,我们在安装程序中包含一个检查点文件,其中包含比特币难度级别变化(每个2015年的块)的每个块的标题。

这使我们只能从钱包出生日期前的检查点进行同步,这节省了大量时间,也是为什么我们要求您在创建钱包期间记录“日期戳”。 因此,如果钱包日期戳相当于块200,050,并且在块200,000处有检查点,那么我们可以同步50块。

由于检查点文件存储在本地,并通过我们的安装程序提供,它使我们能够检测到比特币节点何时试图欺骗使用分叉链(包含假交易)而不是真正的比特币区块链。

连接到本地比特币核心节点

如果MultiBit可以检测到,它将自动连接到在本地主机上运行的Bitcoin Core。 它还连接到其他节点,因为我们使用事务传播来确定事务何时正确发送以及何时可以使用事务更改。 如果我们纯粹依赖单个节点(即使它是可信的),我们也不能确信真正的外部比特币网络正在传递它。

原文地址

https://multibit.org/hd0.4/how-spv-works.html

这个网站对应的产品叫multibit,现已经不再维护,原因是一年前被KeepKey收购了。

:)

作者:diandianxiyu 发表于2017/11/20 15:26:54 原文链接
阅读:112 评论:0 查看评论

UE4实现纹理缩放(将纹理坐标进行缩放)

$
0
0
UE4编辑器蓝图实现纹理的缩放,对于一些效果的实现有很重要的作用。
比如,新加的纹理是这样,看起来块状很大,不是很好看。

如果想要砖块小一些,那么应该怎么做呢?比如下图:


1.如果是自己从Editor Content新导入的图片,导入后会生成Texture资源,将Texture资源拖到视口物体上,会生成Material资源。

然后双击材质资源Tulips_Mat,打开材质蓝图:
然后修改蓝图如下:

然后效果是如下,纹理重复增多,看起来很紧凑:

2.如果是自带的材质,那么在Content中双击材质打开,在材质蓝图界面,修改为如下:


作者:u011417605 发表于2017/11/20 16:00:13 原文链接
阅读:32 评论:0 查看评论

【蓝桥杯】【猜字母】

$
0
0

题目
把abcd…s共19个字母组成的序列重复拼接106次,得到长度为2014的串。
接下来删除第1个字母(即开头的字母a),以及第3个,第5个等所有奇数位置的字母。
得到的新串再进行删除奇数位置字母的动作。
如此下去,最后只剩下一个字母,请写出该字母。
答案是一个小写字母,请通过浏览器提交答案。
不要填写任何多余的内容。

分析
首先利用循环得到2014个长度的字符串,将其变成字符数组。
接着使用双重循环,多次对数组进行字母删除行为,循环跳出的条件是数组中只剩下一个字母为止。

源码

    public static void main(String[] args) {
        String s = "abcdefghijklmnopqrs";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 106; i++) {
            sb.append(s);
        }
        //得到长度为2014的字符数组
        char[] a = sb.toString().toCharArray();

        int N = a.length; //记录还剩下多少字母
        //当只剩下一个字母的时候跳出循环
        ok:while (true) {
            boolean  isJi = true;
            for (int i = 0; i < a.length; i++) {
                if(N == 1) {
                    break ok;
                }

                if (a[i] == '0') {
                    //表示此字母已经删除
                    continue;
                }else {
                    if(isJi) {
                        //如果是奇数的位置上
                        a[i] = '0'; //表示删除此字母
                        isJi = false; //下一次遇到的是偶数位置
                        N--; //字母数量-1
                    }else {
                        isJi = true; //下一次遇到的是奇数位置
                    }
                }
            }
        }

        for (int i = 0; i < a.length; i++) {
            if(a[i] != '0') {
                System.out.println(a[i]);
            }
        }
    }

结果
q

作者:bear_huangzhen 发表于2017/11/20 16:37:27 原文链接
阅读:24 评论:0 查看评论

福建第六届省赛 G题 字符串最大乘积dp

$
0
0

Recently, you have found your interest in string theory. Here is an interesting question about strings.

You are given a string S of length n consisting of the first k lowercase letters.

You are required to find two non-empty substrings (note that substrings must be consecutive) of S, such that the two substrings don't share any same letter. Here comes the question, what is the maximum product of the two substring lengths?

Input

The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

For each test case, the first line consists of two integers n and k. (1 <= n <= 2000, 1 <= k <= 16).

The second line is a string of length n, consisting only the first k lowercase letters in the alphabet. For example, when k = 3, it consists of a, b, and c.

Output

For each test case, output the answer of the question.

Sample Input
4
25 5
abcdeabcdeabcdeabcdeabcde
25 5
aaaaabbbbbcccccdddddeeeee
25 5
adcbadcbedbadedcbacbcadbc
3 2
aaa
Sample Output
6
150
21
0
Hint

One possible option for the two chosen substrings for the first sample is "abc" and "de".

The two chosen substrings for the third sample are "ded" and "cbacbca".

In the fourth sample, we can't choose such two non-empty substrings, so the answer is 0.


【分析】:

k值比较小,可以状态压缩。用二进制每一位代表某一个字母的有无,那么每一个子串有哪些字母,可以构成一个二进制数。例如k=7时某子串“abd”表示位二进制  0001011,最低位是‘a’.然后用该数对应数组下标进行状态的dp。


如果两个状态(子串)进行&运算==0,说明没有公共字母,理所当然的没有相交部分。


第一步,用dp[i]表示状态 i 时的最长子串长度,可用暴力计算保存。


第二步,把状态 i 所包含的子集状态,收进i。例如 i = 0010101,则0000101,0010000等都是i的子集状态。


第三步,枚举状态 i 与其补集状态的乘积,记录最大乘积。

【代码】:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[1<<17];
char s[2010];
int n,k,T;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%d%d",&n,&k);
        scanf("%s",s);
        for(int i=0;i<n;i++)//暴力保存每种状态的最长串
        {
            for(int j=i,w=0;j<n;j++)
            {
                w|=(1<<(s[j]-'a'));
                dp[w]=max(dp[w],j-i+1);
            }
        }
        for(int i=0,r=(1<<k);i<r;i++)//将每种状态的子集状态综合一下,取大值
        {
            for(int j=0;j<k;j++)
                if(i&(1<<j))dp[i]=max(dp[i],dp[i^(1<<j)]);
        }
        int ans=0;
        for(int i=1,r=(1<<k);i<r;i++)//枚举每个状态与其补集的乘积
        {
            int j=i^(r-1);
            ans=max(ans,dp[i]*dp[j]);
        }
        cout<<ans<<endl;
    }
}


作者:winter2121 发表于2017/11/20 16:41:18 原文链接
阅读:27 评论:0 查看评论

EasyUI 树菜单

$
0
0

EasyUI 树菜单

通过ssm框架项目实现EasyUI 的树菜单的单选,复选,异步加载树,同步加载树和树权限控制等功能。

本章知识点

效果图
项目演示

需求:通过SSM框架,实现EasyUI 树菜单的单选,多选,异步加载,同步加载的功能
技术:Spring,SpringMVC,Mybatis,EasyUI
明说:使用EasyUI-Tree,必须严格遵守它的规则,如异步加载树节点的 id,异步加载树返回值的格式等。如果按照其规则来做,你会发现 EasyUI 很简单。反之到处都是吭!
源码:见文章底部
场景:树菜单,在电商中很场景。笔者是在电商公司上班,类目树菜单随处可见。比如给广告员设置类目级别,刊登商品选择类目加载对应的产品规格参数等等
项目结构
项目结构

初始化静态树

大部分的功能,并非一步完成。都是从最基础的功能开始。这里是EasyUI-Tree 基础结构

<ul class="easyui-tree">
    <li>
        <span>根目录</span>
        <ul>
            <li data-options="state:'closed'">
                <span>关闭状态的子目录</span>
                <ul>
                    <li>ITDragon</li>
                    <li>博客</li>
                </ul>
            </li>
            <li>
                <span>默认展开的子目录</span>
                <ul>
                    <li>欢迎</li>
                    <li>You!</li>
                </ul>
            </li>
            <li>你是最棒的!</li>
        </ul>
    </li>
</ul>

Maven Web项目实战

项目框架结构是:Spring,SpringMVC,Mybatis。 没有其他的额外配置,都是基础的整合配置。这里就不贴代码。读者也可以直接从github上clone下来(sql文件也在项目中)。

POJO层

本章的主角,类目实体类 Category.java

package com.itdragon.pojo;

import java.util.Date;

public class Category {
    private Integer id;
    private String name;
    private Integer isLeaf;
    private Integer parentId;
    private Date createddate;
    private Date updateddate;
    private Integer status;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }
    public Integer getIsLeaf() {
        return isLeaf;
    }
    public void setIsLeaf(Integer isLeaf) {
        this.isLeaf = isLeaf;
    }
    public Integer getParentId() {
        return parentId;
    }
    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }
    public Date getCreateddate() {
        return createddate;
    }
    public void setCreateddate(Date createddate) {
        this.createddate = createddate;
    }
    public Date getUpdateddate() {
        return updateddate;
    }
    public void setUpdateddate(Date updateddate) {
        this.updateddate = updateddate;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
}

按照EasyUI规范封装的Tree节点实体类 EUTreeNode.java

package com.itdragon.common.pojo;

/**
 * 树的数据格式(Tree Data Format)
 * 每个节点可以包括下列属性:
 * id:节点的 id,它对于加载远程数据很重要。
 * text:要显示的节点文本。
 * state:节点状态,'open' 或 'closed',默认是 'open'。当设置为 'closed' 时,该节点有子节点,并且将从远程站点加载它们。
 * checked:指示节点是否被选中。
 * attributes:给一个节点添加的自定义属性。
 * children:定义了一些子节点的节点数组
 * 
 * 这里先封装常用的 id,text,state
 */
public class EUTreeNode {

    private long id;
    private long parentId;
    private String text;
    private String state;
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public long getParentId() {
        return parentId;
    }
    public void setParentId(long parentId) {
        this.parentId = parentId;
    }
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
}

说明:
① Category.java 属性 createdDate 和 updatedDate 的类型都是java.util.Date。实际上也可以是 String 类型,这样可以在显示(日期格式化),排序,筛选时减少很多工作量。
② 这里的 Category.java,CategoryExample.java,CategoryMapper.java,CategoryMapper.xml 是通过 Mybatis 提供的逆向工程自动生成的。文章底部会提供链接。

Service 层

提供查询类目的接口 CategoryService.java 感觉怪怪的 -.-||

package com.itdragon.service;

import java.util.List;
import com.itdragon.common.pojo.EUTreeNode;

public interface CategoryService {

    /**
     * 通过父节点,异步加载树菜单
     * @param parentId
     */
    List<EUTreeNode> getCategoryList(int parentId);

    /**
     * 一次全部加载所有树节点
     */
    List<EUTreeNode> getCategoryList();
}

类目接口的实现类 CategoryServiceImpl.java

package com.itdragon.service.impl;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itdragon.common.pojo.EUTreeNode;
import com.itdragon.mapper.CategoryMapper;
import com.itdragon.pojo.Category;
import com.itdragon.pojo.CategoryExample;
import com.itdragon.pojo.CategoryExample.Criteria;
import com.itdragon.service.CategoryService;

@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public List<EUTreeNode> getCategoryList(int parentId) {

        // 1. 创建查询条件
        CategoryExample example = new CategoryExample();
        Criteria criteria = example.createCriteria();
        criteria.andParentIdEqualTo(parentId); // 查询父节点下的所有子节点
        criteria.andStatusEqualTo(0); // 查询未删除状态的菜单
        // TODO 权限拦截
        // 2. 根据条件查询
        List<Category> list = categoryMapper.selectByExample(example);
        List<EUTreeNode> resultList = new ArrayList<>();
        // 3. 把列表转换成 EasyUI Tree 需要的json格式
        for (Category category : list) {
            EUTreeNode node = new EUTreeNode();
            node.setId(category.getId());
            node.setText(category.getName());
            node.setState(category.getIsLeaf() == 1?"open":"closed");
            resultList.add(node);
        }
        // 4. 返回结果
        return resultList;
    }

    @Override
    public List<EUTreeNode> getCategoryList() {

        // 1. 创建查询条件
        CategoryExample example = new CategoryExample();
        Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(0); // 查询未删除状态的菜单
        // TODO 权限拦截
        // 2. 根据条件查询
        List<Category> list = categoryMapper.selectByExample(example);
        List<EUTreeNode> resultList = new ArrayList<>();
        // 3. 把列表转换成 EasyUI Tree 需要的json格式
        for (Category category : list) {
            EUTreeNode node = new EUTreeNode();
            node.setId(category.getId());
            node.setText(category.getName());
            node.setState(category.getIsLeaf() == 1?"open":"closed");
            node.setParentId(category.getParentId());
            resultList.add(node);
        }
        // 4. 返回结果
        return resultList;
    }
}

说明:树菜单的权限拦截,并没有提供代码,是考虑到涉及其他实体类。其实有了思路,其他的都好说………………好吧!我承认自己懒=。=

Controller 层

用于页面跳转的 PageController.java

package com.itdragon.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class PageController {

    @RequestMapping("/")
    public String showIndex() {
        return "tree";
    }

    @RequestMapping("/{page}")
    public String showpage(@PathVariable String page) {
        return page;
    }
}

负责加载类目树菜单的 CategoryController.java

package com.itdragon.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.itdragon.common.pojo.EUTreeNode;
import com.itdragon.service.CategoryService;

@Controller
@RequestMapping("/category")
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    /**
     * http://www.jeasyui.net/plugins/185.html
     * 当展开一个关闭的节点时,如果该节点没有子节点加载,它将通过上面定义的 URL 向服务器发送节点的 id 值作为名为 'id' 的 http 请求参数,以便检索子节点。
     * 所以这里的参数value必须是id,若是其他值则接收不到。缺省值是0,表示初始化一级菜单。
     * 
     * @param parentId
     * @return
     */
    @RequestMapping("/async")
    @ResponseBody
    private List<EUTreeNode> getAsyncCatList(@RequestParam(value="id",defaultValue="0") int parentId) {
        List<EUTreeNode> results = categoryService.getCategoryList(parentId);
        return results;
    }

    @RequestMapping("/sync")
    @ResponseBody
    private List<EUTreeNode> getSyncCatList() {
        List<EUTreeNode> results = categoryService.getCategoryList();
        return results;
    }
}

说明:这里的@RequestParam(value=”id”,defaultValue=”0”),value值必须是id,不能是其他值。

Views视图层

演示EasyUI-Tree 类目树菜单的 tree.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>EasyUI-Tree</title>
<link rel="stylesheet" type="text/css" href="js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<link rel="stylesheet" type="text/css" href="js/jquery-easyui-1.4.1/themes/icon.css" />
<script type="text/javascript" src="js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript" src="js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
</head>
<body class="easyui-layout">
    <div data-options="region:'west',title:'EasyUI 树菜单',split:true" style="width:205px;">
        <ul id="menu" class="easyui-tree" style="margin-top: 10px;margin-left: 5px;">
            <li>
                <span>EasyUI</span>
                <ul>
                    <li>静态树</li>
                    <li>结构为ul li 标签</li>
                    <li>ul定义class为easyui-tree</li>
                </ul>
            </li>
            <li>
                <span>本章知识点</span>
                <ul>
                    <li>创建静态树菜单</li>
                    <li>创建异步树菜单</li>
                    <li>创建异步树多选菜单</li>
                    <li>树菜单权限管理</li>
                </ul>
            </li>
         </ul>
    </div>
    <div id="content" region="center" title="ITDragon博客" style="padding:5px;">
        <span>
            <h3>创建静态树菜单</h3>
            <ul id="" class="easyui-tree">
                <li>
                    <span>父节点</span>
                    <ul>
                        <li>子节点一</li>
                        <li>子节点二</li>
                    </ul>
                </li>
             </ul>
         <h4>使用方法</h4>
         <p>ul 标签 定义 class="easyui-tree"</p>
         <a href="http://www.jeasyui.net/plugins/185.html">EasyUI 树菜单教程 </a> <br/>
         <a href="http://www.jeasyui.net/plugins/180.html">EasyUI 窗口教程 </a>
        </span>
        <hr/>
        <span>
            <h3>创建异步树菜单</h3>
            <a href="javascript:void(0)" class="easyui-linkbutton selectCategory">创建异步树菜单</a>
            <input type="hidden" name="categoryId" style="width: 280px;"></input>
            <br/>
            <h4>创建思路</h4>
            <p>一:初始加载一级类目菜单,通过点击一级类目菜单再查询其子节点菜单</p>
            <p>二:类目表设计实例,一级类目的parentId为0,子节点类目的parentId是父节点类目的id</p>
            <p>三:返回数据结构类型只要满足EasyUI的规范即可</p>
        </span>
        <hr/>
        <span>
            <h3>创建异步树多选菜单</h3>
            <a href="javascript:void(0)" class="easyui-linkbutton selectMoreCategory">创建异步树多选菜单</a>
            <input type="hidden" name="categoryIds" style="width: 280px;"></input>
            <br/>
            <h4>注意</h4>
            <p>若采用异步树加载菜单,会出现勾选父节点。保存后只打印了父节点信息,未打印子节点(因为子节点都没有加载)</p>
            <h4>解决思路</h4>
            <p>让业务每个都点开(不合实际);本章节采用同步加载的方式;你们有没有更好的办法?</p>
            <a href="http://www.jeasyui.net/tutorial/57.html"> EasyUI 采用同步加载教程 </a>
        </span>
        <hr/>
        <span>
            <h3>树菜单权限管理:</h3>
            <p>业务逻辑:需要一张用户组管理表,设置当前登录用户所属组。</p>
            <p>后台逻辑:树菜单表新增字段permission用来匹配用户所属组,说简单点就是多了一层查询条件。</p>
        </span>
    </div>
    <script type="text/javascript">
    $(function(){
        initAsyncCategory ();
        initMoreSyncCategory ();
    });
    // 异步加载树菜单
    function initAsyncCategory (){
        $(".selectCategory").each(function(i,e){
            var _ele = $(e);
            _ele.after("<span style='margin-left:10px;'></span>"); // 避免被按钮遮住
            _ele.unbind('click').click(function(){
                $("<div>").html("<ul>").window({ // 使用 javascript 创建窗口(window)
                    width:'500', height:"450", modal:true, closed:true, iconCls:'icon-save', title:'异步树菜单',
                    onOpen : function(){ // 窗口打开后执行
                        var _win = this;
                        $("ul",_win).tree({
                            url:'/category/async', // 采用异步加载树节点,返回数据的格式要满足EasyUI Tree 的要求
                            animate:true,
                            onClick:function(node){ // 树菜单点击后执行
                                if($(this).tree("isLeaf",node.target)){ // 如果该节点是叶节点就填写到categoryId中,并关闭窗口
                                    _ele.parent().find("[name=categoryId]").val(node.id);
                                    _ele.next().text(node.text).attr("categoryId",node.id);
                                    $(_win).window('close');
                                }
                            }
                        });
                    },
                    onClose : function(){ // 窗口关闭后执行
                        $(this).window("destroy");
                    }
                }).window('open'); // 使用 javascript 打开窗口(window)
            });
        });
    }

    // 同步加载复选树菜单
    function initMoreSyncCategory (){
        $(".selectMoreCategory").each(function(i,e){
            var _ele = $(e);
            _ele.after("<span style='margin-left:10px;'></span>");
            _ele.unbind('click').click(function(){
                $("<div>").html("<ul id='moreItemCat'>").window({ // 使用 javascript 创建窗口(window)
                    width:'500', height:"450", modal:true, closed:true, iconCls:'icon-save', title:'多选树菜单,关闭窗口后保存数据',
                    onOpen : function(){ // 窗口打开后执行
                        var _win = this;
                        $("ul",_win).tree({
                            url:'/category/sync', // 采用同步的方式加载所有树节点
                            animate:true,
                            checkbox:true,  // js 声明树菜单可以复选
                            loadFilter: function(rows){
                                return convert(rows);
                            }
                        });
                    },
                    onClose : function(){ // 窗口关闭后执行
                        var nodes = $("#moreItemCat").tree('getChecked');
                        var categoryIds = '';
                        var categoryTexts = '';
                        for(var i = 0; i < nodes.length; i++){
                            if ('' != categoryIds) {
                                categoryIds += ',';
                                categoryTexts += ' , ';
                            }
                            categoryIds += nodes[i].id;
                            categoryTexts += nodes[i].text;
                        }
                        _ele.parent().find("[name=categoryIds]").val(categoryIds);
                        _ele.next().text(categoryTexts).attr("categoryId",categoryTexts);
                        $(this).window("destroy");
                    }
                }).window('open'); // 使用 javascript 打开窗口(window)
            });
        });
    }

    // 官方提供的 js 解析 json 代码
    function convert(rows){
        function exists(rows, parentId){
            for(var i=0; i<rows.length; i++){
                if (rows[i].id == parentId) return true;
            }
            return false;
        }
        var nodes = [];
        for(var i=0; i<rows.length; i++){   // get the top level nodes
            var row = rows[i];
            if (!exists(rows, row.parentId)){
                nodes.push({
                    id:row.id,
                    text:row.text,
                    state:row.state
                });
            }
        }
        var toDo = [];
        for(var i=0; i<nodes.length; i++){
            toDo.push(nodes[i]);
        }
        while(toDo.length){
            var node = toDo.shift();    // the parent node
            for(var i=0; i<rows.length; i++){   // get the children nodes
                var row = rows[i];
                if (row.parentId == node.id){
                    var child = {id:row.id,text:row.text,state:row.state};
                    if (node.children){
                        node.children.push(child);
                    } else {
                        node.children = [child];
                    }
                    toDo.push(child);
                }
            }
        }
        return nodes;
    }
    </script>
</body>
</html>

说明:
① tree.jsp 除了EasyUI-Tree 的知识点外,还涉及了一点点窗口的知识

  • 使用 javascript 创建窗口(window)
<div id="win"></div>
$('#win').window({
    width:600,
    height:400,
    modal:true
});
  • 打开和关闭窗口(window)
$('#win').window('open'); // open a window
$('#win').window('close'); // close a window

② tree.jsp 主要包含了单选异步加载树菜单和多选同步加载树菜单两大知识点,所以内容较长,请耐心阅读。
③ 若异步加载树菜单,支持多选,会出现子节点没有打印的问题

总结

  • 如何初始化静态的树菜单。
  • 如何实现异步加载树菜单,单选后显示在页面上。
  • 如何实现同步加载树菜单,多选后显示在页面上。
  • 树菜单表的设计思路。

源码:
https://github.com/ITDragonBlog/daydayup/tree/master/EasyUI/EasyUI-tree
逆向工程:
https://github.com/ITDragonBlog/daydayup/tree/master/mybatis/generatorSqlmapCustom

最后,EasyUI 树菜单到这里就结束了,感谢大家的阅读。觉得不错的可以点个赞!

作者:qq_19558705 发表于2017/11/20 16:52:27 原文链接
阅读:30 评论:0 查看评论

Codeforces Round #447 (Div. 2) A-C题解

$
0
0

作对一个题还涨分,我这分数是有多低,B题明知道爆表还不会改,难受。

A. QAQ
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

"QAQ" is a word to denote an expression of crying. Imagine "Q" as eyes with tears and "A" as a mouth.

Now Diamond has given Bort a string consisting of only uppercase English letters of length n. There is a great number of "QAQ" in the string (Diamond is so cute!).

Bort wants to know how many subsequences "QAQ" are in the string Diamond has given. Note that the letters "QAQ" don't have to be consecutive, but the order of letters should be exact.

Input

The only line contains a string of length n (1 ≤ n ≤ 100). It's guaranteed that the string only contains uppercase English letters.

Output

Print a single integer — the number of subsequences "QAQ" in the string.

Examples
input
QAQAQYSYIOIWIN
output
4
input
QAQQQZZYNOIWIN
output
3
Note

In the first example there are 4 subsequences "QAQ": "QAQAQYSYIOIWIN", "QAQAQYSYIOIWIN", "QAQAQYSYIOIWIN", "QAQAQYSYIOIWIN".

大水题一发,100个字符,三层暴力都不超时,幸好这题手速A到,才加了50多分。

代码实现;

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<cstdio>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
char map[105];
int q[105],a[105];
int main()
{
	int n,i,j,k;
	while(~scanf("%s",map))
	{
		n=strlen(map);
		int l=0,r=0;
		int ans=0;
		for(i=0;i<n;i++)
		{
			if(map[i]=='Q')
			l++;
			if(map[i]=='A')
			{
				r=0;
				for(j=i+1;j<n;j++)
				if(map[j]=='Q')
				r++;
				ans+=l*r;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

B. Ralph And His Magic Field
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Ralph has a magic field which is divided into n × m blocks. That is to say, there are n rows and m columns on the field. Ralph can put an integer in each block. However, the magic field doesn't always work properly. It works only if the product of integers in each row and each column equals to k, where k is either 1 or -1.

Now Ralph wants you to figure out the number of ways to put numbers in each block in such a way that the magic field works properly. Two ways are considered different if and only if there exists at least one block where the numbers in the first way and in the second way are different. You are asked to output the answer modulo 1000000007 = 109 + 7.

Note that there is no range of the numbers to put in the blocks, but we can prove that the answer is not infinity.

Input

The only line contains three integers nm and k (1 ≤ n, m ≤ 1018k is either 1 or -1).

Output

Print a single number denoting the answer modulo 1000000007.

Examples
input
1 1 -1
output
1
input
1 3 1
output
1
input
3 3 -1
output
16
Note

In the first example the only way is to put -1 into the only block.

In the second example the only way is to put 1 into every block.


找到规律容易吗?明知道10^18*10^18会爆,欧拉公式不会用啊,眼睁睁的看着这个题没过,难受啊。
题意是有n*m个格子的矩形,要求每个格子随便填数,使得结果每行每列和总的积为k,k只能是-1或1,问有多少种方法。
此题只能填1或-1,然后会发现当m+n是奇数的时候是无法构造的,即输出0. m*n的格子跟(m-1)*(n-1)的格子的摆放顺序有关,然后就是一波解释,不懂的可以百度,最后得到总数是2^(m-1)*(n-1),解决掉爆表问题,就ok了。

代码实现:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<cstdio>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}

int main()
{
	ll a,b,x;
	while(cin>>a>>b>>x)
	{
		if(x==-1&&(a+b)%2)
		{
			cout<<"0"<<endl;
			continue;
		}
		a--;
		b--;
		ll ans=fpow(2,a);
		ll sum=fpow(ans,b);
		cout<<sum<<endl;
	}
	return 0;
}

C. Marco and GCD Sequence
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

In a dream Marco met an elderly man with a pair of black glasses. The man told him the key to immortality and then disappeared with the wind of time.

When he woke up, he only remembered that the key was a sequence of positive integers of some length n, but forgot the exact sequence. Let the elements of the sequence be a1, a2, ..., an. He remembered that he calculated gcd(ai, ai + 1, ..., aj) for every1 ≤ i ≤ j ≤ n and put it into a set Sgcd here means the greatest common divisor.

Note that even if a number is put into the set S twice or more, it only appears once in the set.

Now Marco gives you the set S and asks you to help him figure out the initial sequence. If there are many solutions, print any of them. It is also possible that there are no sequences that produce the set S, in this case print -1.

Input

The first line contains a single integer m (1 ≤ m ≤ 1000) — the size of the set S.

The second line contains m integers s1, s2, ..., sm (1 ≤ si ≤ 106) — the elements of the set S. It's guaranteed that the elements of the set are given in strictly increasing order, that means s1 < s2 < ... < sm.

Output

If there is no solution, print a single line containing -1.

Otherwise, in the first line print a single integer n denoting the length of the sequence, n should not exceed 4000.

In the second line print n integers a1, a2, ..., an (1 ≤ ai ≤ 106) — the sequence.

We can show that if a solution exists, then there is a solution with n not exceeding 4000 and ai not exceeding 106.

If there are multiple solutions, print any of them.

Examples
input
4
2 4 6 12
output
3
4 6 12
input
2
2 3
output
-1
Note

In the first example 2 = gcd(4, 6), the other elements from the set appear in the sequence, and we can show that there are no values different from 246 and 12 among gcd(ai, ai + 1, ..., aj) for every 1 ≤ i ≤ j ≤ n.


一道思维题,意思是找出一列数,使得任意两个数的gcd都在原数组中出现,任意数出这么一组数。
首先使新的序列构造出来,那么原序列中最小的数肯定是其他任何数的因子,构造的时候只需要把最小的数插入在原序列中间即可,这样可以保证gcd出来的结果不是自己就是最小的数。

代码实现:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<cstdio>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
int map[maxn];

int main()
{
	int n,i,j,k;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&map[i]);
	}
	for(i=1;i<n;i++)
	{
		if(map[i]%map[0]!=0)
		{
			cout<<"-1"<<endl;
			return 0;
		}
	}
	cout<<2*n<<endl;
	for(i=0;i<n;i++)
	{
		cout<<map[i]<<' '<<map[0]<<' ';
	}
	cout<<endl;
}


作者:Ever_glow 发表于2017/11/20 16:52:27 原文链接
阅读:19 评论:0 查看评论

Android使用Thread的interrupt与sleep,重启或暂停线程任务

$
0
0
Android使用Thread的interrupt与sleep,重启或暂停线程任务


本文给出一个例子,简单说明如何在Android诸如Activity中,重启或者暂停一个正在无限运作的线程。
需求描述:假设在Android的Activity中,有一个线程,永不停息的运作,若当前Activity处于用户可见状态时候,每隔一秒输出一个自增长的计数器值,但是当Activity处于用户不可见时候,暂停线程输出,即中断线程执行。
实现这一机制的关键点简言之,借助Thread的sleep,让sleep在一定条件下(比如一个状态机布尔值)休眠一个极大值Long.MAX_VALUE。然后在Android的Activity生命周期回调中,重新赋值状态机布尔值,同时使用Thread的interrupt方法,打断当前处于休眠状态的线程,使之重新恢复正常运转。
代码如下:
package zhangphil.thread;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    private String TAG = "输出";
    private int count = 0;
    private boolean RUN = true;

    private LongTimeWork mThread = new LongTimeWork();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mThread.start();
    }

    private class LongTimeWork extends Thread {
        @Override
        public void run() {
            while (true) {
                try {
                    if (!RUN) {
                        Thread.sleep(Long.MAX_VALUE);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }

                count++;
                Log.d(TAG, count + "");

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        RUN = true;
        mThread.interrupt();
    }

    @Override
    protected void onPause() {
        super.onPause();

        RUN = false;
    }
}

作者:zhangphil 发表于2017/11/20 17:12:55 原文链接
阅读:23 评论:0 查看评论

Go实战--golang中使用echo和MySQL搭建api(labstack/echo、go-sql-driver/mysql)

$
0
0

生命不止,继续 go go go!!!

前面有几篇博客跟大家分享了一个golang的框架iris:
Go实战–也许最快的Go语言Web框架kataras/iris初识四(i18n、filelogger、recaptcha)

Go实战–也许最快的Go语言Web框架kataras/iris初识三(Redis、leveldb、BoltDB)

Go实战–也许最快的Go语言Web框架kataras/iris初识二(TOML、Cache、Cookie)

Go实战–也许最快的Go语言Web框架kataras/iris初识(basic认证、Markdown、YAML、Json)

今天就跟大家介绍另一个golang的优秀的框架echo,今天作为开篇就写一个简单的Web应用吧。

echo

High performance, extensible, minimalist Go web framework

特性:
Optimized HTTP router which smartly prioritize routes
Build robust and scalable RESTful APIs
Group APIs
Extensible middleware framework
Define middleware at root, group or route level
Data binding for JSON, XML and form payload
Handy functions to send variety of HTTP responses
Centralized HTTP error handling
Template rendering with any template engine
Define your format for the logger
Highly customizable
Automatic TLS via Let’s Encrypt
HTTP/2 support

官网:
https://echo.labstack.com/

github地址:
https://github.com/labstack/echo

Star: 8707

获取:
go get github.com/labstack/echo

mysql

golang中使用MySQL请参考博客:
Go实战–go语言操作MySQL数据库(go-sql-driver/mysql)

这里就不详细介绍了。

实战

我们先建立一个MySQL的表,然后插入一些数据。

create table excuses (id char(20), quote char(20));
insert into excuses (id, quote) VALUES ("1", "hey jude");

代码:

package main

import (
    "database/sql"
    "fmt"
    "net/http"
    _ "github.com/go-sql-driver/mysql"
    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
)

type (
    Excuse struct {
        Error string `json:"error"`
        Id    string `json:"id"`
        Quote string `json:"quote"`
    }
)

func main() {
    // Echo instance
    e := echo.New()

    // Middleware
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
        AllowOrigins: []string{"*"},
        AllowMethods: []string{echo.GET, echo.PUT, echo.POST, echo.DELETE},
    }))

    // Route => handler
    e.GET("/", func(c echo.Context) error {
        db, err := sql.Open("mysql", "root:wangshubo@/test?charset=utf8")

        if err != nil {
            fmt.Println(err.Error())
            response := Excuse{Id: "", Error: "true", Quote: ""}
            return c.JSON(http.StatusInternalServerError, response)
        }
        defer db.Close()

        var quote string
        var id string
        err = db.QueryRow("SELECT id, quote FROM excuses ORDER BY RAND() LIMIT 1").Scan(&id, &quote)

        if err != nil {
            fmt.Println(err)
        }

        fmt.Println(quote)
        response := Excuse{Id: id, Error: "false", Quote: quote}
        return c.JSON(http.StatusOK, response)
    })

    e.GET("/id/:id", func(c echo.Context) error {
        requested_id := c.Param("id")
        fmt.Println(requested_id)
        db, err := sql.Open("mysql", "root:wangshubo@/test?charset=utf8")

        if err != nil {
            fmt.Println(err.Error())
            response := Excuse{Id: "", Error: "true", Quote: ""}
            return c.JSON(http.StatusInternalServerError, response)
        }
        defer db.Close()

        var quote string
        var id string
        err = db.QueryRow("SELECT id, quote FROM excuses WHERE id = ?", requested_id).Scan(&id, &quote)

        if err != nil {
            fmt.Println(err)
        }

        response := Excuse{Id: id, Error: "false", Quote: quote}
        return c.JSON(http.StatusOK, response)
    })

    e.Logger.Fatal(e.Start(":4000"))
}

浏览器输入:
http://localhost:4000
http://localhost:4000/id/1

输出:

// 20171120170032
// http://localhost:4000/id/1

{
  "error": "false",
  "id": "1",
  "quote": "hey jude"
}

这里写图片描述

作者:wangshubo1989 发表于2017/11/20 17:13:00 原文链接
阅读:380 评论:0 查看评论

福建第六届省赛 H 贪心 哈夫曼思想

$
0
0

ZB loves playing StarCraft and he likes Zerg most!

One day, when ZB was playing SC2, he came up with an idea:

He wants to change the queen's ability, the queen's new ability is to choose a worker at any time, and turn it into an egg, after K units of time, two workers will born from that egg. The ability is not consumed, which means you can use it any time without cooling down.

Now ZB wants to build N buildings, he has M workers initially, the i-th building costs t[i] units of time, and a worker will die after he builds a building. Now ZB wants to know the minimum time to build all N buildings.

Input

The first line contains an integer T, meaning the number of the cases. 1 <= T <= 50.

For each test case, the first line consists of three integers N, M and K. (1 <= N, M <= 100000, 1 <= K <= 100000).

The second line contains N integers t[1] ... t[N](1 <= t[i] <= 100000).

Output

For each test case, output the answer of the question.

Sample Input
2
3 1 1
1 3 5
5 2 2
1 1 1 1 10
Sample Output
6
10
Hint

For the first example, turn the first worker into an egg at time 0, at time 1 there’s two worker. And use one of them to build the third building, turn the other one into an egg, at time 2, you have 2 workers and a worker building the third building. Use two workers build the first and the second building, they are built at time 3, 5, 6 respectively.


【分析】:按照贪心策略,肯定优先派人先干着耗时长的建筑,人数不够的话要在耗时次长(耗时长的都安排上了)的建筑上同时分裂员工。因为耗时短的可以尽量往后拖一拖。

然后可以知道,把分裂员工用掉的时间k尽量放到时间小的建筑上,这样可以尽量不超越最大建筑。

然后逆向思维,排个序,从小建筑开始安排k,需要安排n-m次


哈夫曼思想,取两个最小耗时,小者可以往后拖一拖,大者必须要安排k了。

安排n-m次;

用优先队列维护。

【代码】:

#include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{
    int T,n,m,k,x;
    cin>>T;
    while(T--)
    {
        while(!q.empty())q.pop();
        cin>>n>>m>>k;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&x);
            q.push(x);
        }
        while(n>m)//人不够,还要分裂
        {
            q.pop();
            int t=q.top();q.pop();
            q.push(t+k);
            n--;
        }
        int ans;
        while(!q.empty())
        {
            ans=q.top();q.pop();
        }
        cout<<ans<<endl;
    }
}


作者:winter2121 发表于2017/11/20 17:39:34 原文链接
阅读:13 评论:0 查看评论

Java线程与线程状态

$
0
0

根据Java的DOC文档介绍,在JVM中,Java的线程存在以下5种状态:

  1. NEW:线程通过构造方法创建出来之后的状态,表示线程并未启动。
  2. RUNNABLE:线程可运行的状态,但是这里的可运行表示的是JVM中线程的状态,不要与操作系统的进程的运行中相混淆。
  3. BLOCKED:由于其他线程持有监视器锁,当前线程正在等待获取监视器锁(这个状态是JVM标记的,且这个等待是由JVM唤醒)
  4. WAITING:当前线程正在等待其他线程唤醒(这个状态是调用特定的API主动进行等待,且只能由其他线程唤醒)
  5. TIMED_WAITING:带有超时机制的WAITING,超时之后由JVM进行唤醒。

以下是Java线程状态的流转图:

Java线程状态流转图

以下是一个线程简单运行的示例:

public static void main(String[] args) {
    //初始化线程对象
    Thread thread=new Thread(new Runnable() {

        @Override
        public void run() {
            //输出线程状态
            System.out.println("thread running:"+Thread.currentThread().getState());
        }
    });
    //线程并未开始运行,状态为NEW
    System.out.println("before start:"+thread.getState());
    thread.start();
    //线程如果依然存活,则死循环
    while(thread.isAlive()){

    }
    //此时线程已终止,状态为TERMINATED
    System.out.println("thread finished:"+thread.getState());
}

运行结果如下:

before start:NEW
thread running:RUNNABLE
thread finished:TERMINATED

这个例子展示了线程正常运行的流程,即NEW->RUNNABLE->TERMINATED。

  1. 我这个例子线程的构建是通过匿名内部类来构建一个Runnable的对象,作为Thread实际运行执行的逻辑(输出线程运行中的状态)。
  2. 使用了Thread.isAlive()这个API获取线程是否存活,通过while做空转确保最后输出线程状态时为TERMINATED。
作者:a158123 发表于2017/11/20 18:24:06 原文链接
阅读:0 评论:0 查看评论

Python基础入门之函数二

$
0
0

5.4、Python函数之返回多值


函数可以返回多个值吗?答案是肯定的。

比如在游戏中经常需要从一个点移动到另一个点,给出坐标、位移和角度,就可以计算出新的坐标:

# math包提供了sin()和 cos()函数,我们先用import引用它:

import math

def move(x, y, step, angle):

    nx = x + step * math.cos(angle)

    ny = y - step * math.sin(angle)

    return nx, ny

这样我们就可以同时获得返回值:

>>> x, y = move(100, 100, 60, math.pi / 6)

>>> print x, y

151.961524227 70.0

但其实这只是一种假象,Python函数返回的仍然是单一值:

>>> r = move(100, 100, 60, math.pi / 6)

>>> print r

(151.96152422706632, 70.0)

用print打印返回结果,原来返回值是一个tuple

但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以函数返回几个值就需要几个变量去接收(除了一个变量去接收函数时),接收变量多了或少了,代码都会报错ValueError。Python的函数返回多值其实就是返回一个tuple,但写起来更方便。

任务4

一元二次方程的定义是:ax² + bx + c = 0

请编写一个函数,返回一元二次方程的两个解。

注意:Python的math包提供了sqrt()函数用于计算平方根。


5.6、Python之定义默认参数


定义函数的时候,还可以有默认参数。

例如Python自带的 int() 函数,其实就有两个参数,我们既可以传一个参数,又可以传两个参数:

>>> int('123')

123

>>> int('123', 8)

83

int()函数的第二个参数是转换进制,如果不传,默认是十进制 (base=10),如果传了,就用传入的参数。

可见,函数的默认参数的作用是简化调用,你只需要把必须的参数传进去。但是在需要的时候,又可以传入额外的参数来覆盖默认参数值。

我们来定义一个计算 x 的N次方的函数:

def power(x, n):

    s = 1

    while n > 0:

        n = n - 1

        s = s * x

    return s

假设计算平方的次数最多,我们就可以把 n 的默认值设定为 2:

def power(x, n=2):

    s = 1

    while n > 0:

        n = n - 1

        s = s * x

    return s

这样一来,计算平方就不需要传入两个参数了:

>>> power(5)

25

由于函数的参数按从左到右的顺序匹配,所以默认参数只能定义在必需参数的后面:

# OK:

def fn1(a, b=1, c=2):

    pass

# Error:

def fn2(a=1, b):

    pass

任务6

请定义一个 greet() 函数,它包含一个默认参数,如果没有传入,打印 'Hello, world.',如果传入,打印 'Hello, xxx.'


5.7Python之定义可变参数


如果想让一个函数能接受任意个参数,我们就可以定义一个可变参数:

def fn(*args):

    print args

可变参数的名字前面有个 号,我们可以传入0个、1个或多个参数给可变参数:

>>> fn()

()

>>> fn('a')

('a',)

>>> fn('a', 'b')

('a', 'b')

>>> fn('a', 'b', 'c')

('a', 'b', 'c')

可变参数也不是很神秘,Python解释器会把传入的一组参数组装成一个tuple传递给可变参数,因此,在函数内部,直接把变量 args 看成一个 tuple 就好了。

定义可变参数的目的也是为了简化调用。假设我们要计算任意个数的平均值,就可以定义一个可变参数:

def average(*args):

    ...

这样,在调用的时候,可以这样写:

>>> average()

0

>>> average(1, 2)

1.5

>>> average(1, 2, 2, 3, 4)

2.4

任务7

请编写接受可变参数的 average() 函数。


任务答案:

任务4:

#提示:求根公式:x = (-b±√(b*b-4ac))/2a

import math


def quadratic_equation(a, b, c):

    t = math.sqrt(b * b - 4 * a * c)

    x1 = (-b + t) / (2 * a)

    x2 = (-b - t) / (2 * a)

    return x1,x2


print quadratic_equation(2, 3, 0)

print quadratic_equation(1, -6, 5)


任务6:

def greet(a = 'world'):

    print 'Hello,'+ a + '.'


greet()

greet('Bart')


任务7:

def average(*args):

    if len(args) <= 0:

        return 0.0

    sum = 0.0

    avg = 0.0

    for i in args:

        sum = sum + i

    avg = sum / len(args)

    return avg

print average()

print average(1, 2)

print average(1, 2, 2, 3, 4)


文章中缺少了5.5、函数之递归函数,为了更好的理解,我准备单列出一篇,用来讲,敬请期待!!!




作者:hbblzjy 发表于2017/11/20 19:22:53 原文链接
阅读:0 评论:0 查看评论

Unity Shader 学习笔记(15) 立方体纹理、反射、折射

$
0
0

Unity Shader 学习笔记(15) 立方体纹理、反射、折射

参考书籍:《Unity Shader 入门精要》


立方体纹理(Cubemap)

是环境映射(Environment Mapping)的一种实现方法。用于模拟物体周围的环境,使用了环境映射的物体可以让物体像镜子一样反射周围环境。

天空盒子(Skybox)

用于模拟室内背景。

创建环境映射的立方体纹理方法有三种:
- 由特殊布局的纹理创建。提供如立方体展开图的交叉布局、全景布局等。
- 创建一个Cubemap,把6张纹理拖拽到面板中。
- 由脚本生成,可以从任意位置观察场景的图像存储到6张图像中。调用Camera.RenderToCubemap(cubemap)生成,创建cubemap要标记Readable才能修改。


反射(Reflection)

用环境映射纹理代替了高光反射。

Properties {
    _Color ("Color Tint", Color) = (1, 1, 1, 1)
    _ReflectColor ("Reflection Color", Color) = (1, 1, 1, 1)    // 反射颜色
    _ReflectAmount ("Reflect Amount", Range(0, 1)) = 1          // 反射程度
    _Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}        // 环境纹理
}
struct v2f {
    ...
    fixed3 worldViewDir : TEXCOORD2;
    fixed3 worldRefl : TEXCOORD3;
    SHADOW_COORDS(4)
};

v2f vert(a2v v) {
    v2f o;
    ...

    o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);    //计算视角方向
    o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);  // 计算反射方向

    TRANSFER_SHADOW(o);
    return o;
}

fixed4 frag(v2f i) : SV_Target {
    ...

    // 对立方体采样,CG的texCUBE函数。
    fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb * _ReflectColor.rgb;

    UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

    // 对漫反射和立方体做插值,作为漫反射和高光反射的颜色。
    fixed3 color = ambient + lerp(diffuse, reflection, _ReflectAmount) * atten;

    return fixed4(color, 1.0);
}


折射(Refraction)

斯涅耳定律(Snell’s Law),n为折射率:
- n1sinθ1 = n2sinθ2

在实际中,需要计算两次折射,第一次是光线进入内部,第二次是内部射出。但要在实时渲染时模拟第二次折射比较复杂,所以通常只模拟第一次折射。

Properties {
    _Color ("Color Tint", Color) = (1, 1, 1, 1)
    _RefractColor ("Refraction Color", Color) = (1, 1, 1, 1)        // 折射颜色
    _RefractAmount ("Refraction Amount", Range(0, 1)) = 1           // 折射程度
    _RefractRatio ("Refraction Ratio", Range(0.1, 1)) = 0.5         // 折射比例
    _Cubemap ("Refraction Cubemap", Cube) = "_Skybox" {}            // 模拟折射环境纹理
}
v2f vert(a2v v) {
    v2f o;
    ...

    o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
    // 计算折射方向,第一个参数为入射方向,第二个参数是表面法线,第三个参数是入射折射率和出射比值。
    o.worldRefr = refract(-normalize(o.worldViewDir), normalize(o.worldNormal), _RefractRatio);

    TRANSFER_SHADOW(o);
    return o;
}

fixed4 frag(v2f i) : SV_Target {
    ...
    // 对立方体采样
    fixed3 refraction = texCUBE(_Cubemap, i.worldRefr).rgb * _RefractColor.rgb;

    UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);

    // 混合漫反射颜色和折射颜色
    fixed3 color = ambient + lerp(diffuse, refraction, _RefractAmount) * atten;
    return fixed4(color, 1.0);
}

菲涅尔反射(Fresnel reflection)

即光线照射物体时,一部分发生反射,另一部分进入物体发生折射或散射。

近处湖面可以直接看到湖底(折射),远处湖面就只能看到镜面反射了。

Schilick菲涅尔近似等式(F0为反射系数,v为视角方向,n为表面法线):

Empricial菲涅尔近似等式:

使用Schilick菲涅尔近似等式实现:

Properties {
    _Color ("Color Tint", Color) = (1, 1, 1, 1)
    _FresnelScale ("Fresnel Scale", Range(0, 1)) = 0.5  // 对应F0
    _Cubemap ("Reflection Cubemap", Cube) = "_Skybox" {}
}
v2f vert(a2v v) {
    v2f o;
    ...
    // 同反射计算
    o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);
    o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);

    TRANSFER_SHADOW(o);
    return o;
}

fixed4 frag(v2f i) : SV_Target {
    ...

    fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb;

    // Schlick菲涅尔近似等式
    fixed fresnel = _FresnelScale + (1 - _FresnelScale) * pow(1 - dot(worldViewDir, worldNormal), 5);

    fixed3 color = ambient + lerp(diffuse, reflection, saturate(fresnel)) * atten;

    return fixed4(color, 1.0);
}

普通反射和菲涅尔反射系数都为 0 对比:

普通反射和菲涅尔反射系数都为 0.2 对比:

普通反射和菲涅尔反射系数都为 1 对比(通过公式可以看出两者值是一样的):

作者:l773575310 发表于2017/11/20 16:11:26 原文链接
阅读:30 评论:0 查看评论

leetcode-455. Assign Cookies

$
0
0

455. Assign Cookies

Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

Note:
You may assume the greed factor is always positive. 
You cannot assign more than one cookie to one child.

Example 1:

Input: [1,2,3], [1,1]

Output: 1

Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. 
And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.
You need to output 1.

Example 2:

Input: [1,2], [1,2,3]

Output: 2

Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. 
You have 3 cookies and their sizes are big enough to gratify all of the children, 
You need to output 2.

题意:

假设给定 sg 两个数组,有 s.length 个孩子,g.length 的饼干,s 中的数字表示每个孩子需要的最少饼干的大小, g 中的元素表示你所拥有的每块饼干的大小。

要求每个孩子只能给一块饼干,必须满足大小的要求

求满足条件的孩子的数量


解析:对于每个孩子的要求,只需要给大于要求的最小饼干即可。 所以排序完成后,一个个找即可


solution:

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int i = 0;
        for(int j = 0; i<g.length &&  j< s.length;j++){
            if(g[i]<=s[j]) i++;
        }
        return i;

    }
}



作者:qq_32832023 发表于2017/11/20 19:38:58 原文链接
阅读:42 评论:0 查看评论

js将json自动转html表格实例

$
0
0

Js自动将json格式转成html table形式展现,做下笔记

截图如下:


html代码:

<html> 
<head> 
<title></title> 
<script type="text/javascript">      
          var jsonArray = [{"编号":"1001","名称":"k-means","描述":"K-means算法是硬聚类算法,是典型的基于原型的目标函数聚类方法的代表","操作":"<button>编辑</button>"},{"编号":"1002","名称":"restful","描述":"一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件","操作":"<button>删除</button>"}]; 
          var headArray = []; 
          function parseHead(oneRow) { 
                        for ( var i in oneRow) { 
                                headArray[headArray.length] = i; 
                         } 
            } 
            function appendTable() { 
                          parseHead(jsonArray[0]); 
                          var div = document.getElementById("div1");  
                          var table = document.createElement("table"); 
                          var thead = document.createElement("tr"); 
                          for ( var count = 0; count < headArray.length; count++) { 
                                    var td = document.createElement("th"); 
                                    td.innerHTML = headArray[count]; 
                                    thead.appendChild(td); 
                           } 
                           table.appendChild(thead); 
                          for ( var tableRowNo = 0; tableRowNo < jsonArray.length; tableRowNo++) { 
                                    var tr = document.createElement("tr"); 
                                    for ( var headCount = 0; headCount < headArray.length; headCount++) { 
                                            var cell = document.createElement("td"); 
                                            cell.innerHTML = jsonArray[tableRowNo][headArray[headCount]]; 
                                            tr.appendChild(cell); 
                                    } 
                                    table.appendChild(tr); 
                         } 
                          div.appendChild(table); 
        }                        
           
</script> 
    <style> 
        table { 
            width: 900px; 
            padding: 0 ; 
            margin: 20 auto; 
            border-collapse: collapse; 
        } 
        td,th { 
            border: 1px solid #ddd; 
            padding: 6px 6px 6px 12px; 
            color: #4f6b72; 
            text-align: center; 
        } 
        th { 
            background: #d3d3d3; 
             
        } 
    </style> 
</head> 
<body onload="appendTable(jsonArray);"> 
         <h3 align="center">json示例代码</h3>
         <pre>
                   var jsonArray = [{"编号":"1001","名称":"k-means","描述":"K-means算法是硬聚类算法,是典型的基于原型的目标函数聚类方法的代表","操作":"<button>编辑</button>"},
                  {"编号":"1002","名称":"restful","描述":"一种软件架构风格、设计风格,而不是标准,只是提供了一组设计原则和约束条件","操作":"<button>删除</button>"}];          
         </pre>
    <div id="div1"></div> 
</body> 
</html>



作者:ardo_pass 发表于2017/11/20 20:04:27 原文链接
阅读:23 评论:0 查看评论

layui实现数据分页功能

$
0
0

官网layui table演示页面:http://www.layui.com/demo/table.html

示例截图:


页面引入layui.css、 layui.js

<div id="pTable" style="width: 1200px;">
                  <table class="layui-table" id="layui_table_id" lay-filter="test">
             </table>
             <div id="laypage"></div>
          </div>


前台js

var limitcount = 10;
    var curnum = 1;
    //列表查询方法
    function productsearch(productGroupId,start,limitsize) {
        layui.use(['table','laypage','laydate'], function(){
            var table = layui.table,
                laydate=layui.laydate,
                laypage = layui.laypage;
            table.render({
                elem: '#layui_table_id'
                , url: '<%=path%>/xx/pListQuery.html?pId='+productGroupId+'¤tPage='+ start+'¤tNumber=' + limitsize
                /*, where:{pagename:start,pagelimit:limitsize} //传参*/
                , cols: [[
                    {field: 'productId', title: 'ID', width: '170', sort: true}
                    , {field: 'productName', title: '名称', width: '450'}
                    , {field: 'productState', title: '状态', width: '100'}
                    , {field: 'effectTime', title: '生效时间', width: '120', sort: true}
                    , {field: 'invalidTime', title: '失效时间', width: '120', sort: true}
                    , {field: 'productCost', title: '成本', width: '100', sort: true}
                    , {field: 'poperation', title: '操作', width: '100',fixed: 'right', toolbar: '#barDemo'}
                ]]
                , page: false
                , height: 430
                ,done: function(res, curr, count){
                    //如果是异步请求数据方式,res即为你接口返回的信息。
                    //如果是直接赋值的方式,res即为:{data: [], count: 99} data为当前页数据、count为数据总长度
                    laypage.render({
                        elem:'laypage'
                        ,count:count
                        ,curr:curnum
                        ,limit:limitcount
                        ,layout: ['prev', 'page', 'next', 'skip','count','limit']
                        ,jump:function (obj,first) {
                            if(!first){
                                curnum = obj.curr;
                                limitcount = obj.limit;
                                //console.log("curnum"+curnum);
                                //console.log("limitcount"+limitcount);
                                //layer.msg(curnum+"-"+limitcount);
                                productsearch(productGroupId,curnum,limitcount);
                            }
                        }
                    })
                }
            })
 
            //监听工具条
            table.on('tool(test)', function(obj){ //注:tool是工具条事件名,test是table原始容器的属性 lay-filter="对应的值"
                var data = obj.data //获得当前行数据
                    ,layEvent = obj.event; //获得 lay-event 对应的值
                if(layEvent === 'detail'){
                    viewLableInfo(data.attrId);
                    layer.msg(data.attrId);
                } else if(layEvent === 'del'){
                    layer.msg('删除');
                } else if(layEvent === 'edit'){
                    layer.msg('编辑操作');
                }
            });
            //常规用法
            laydate.render({
                elem: '#createDate'
            });
            //常规用法
            laydate.render({
                elem: '#processingTime'
            });
 
        });
    }
      var pId = '${pGBean.pgId }';
productsearch(pId, curnum, limitcount);


业务逻辑层

@Override
      public String queryList (HttpServletRequest request) {
           String total = "";
           String pId = request.getParameter("pId");
            int currentNumber = Integer.parseInt(request.getParameter("currentNumber"));
        String currentPage = request.getParameter("currentPage") == null ? "1" : request.getParameter("currentPage");
        //分页处理,显示第一页的30条数据(默认值)
        PageHelper.startPage(Integer.parseInt(currentPage), currentNumber);
        List<PExl> list = exportDao.queryList (pId);
        if(list.size() > 0){
            total = list.get(0).getTotal();
        }
       
        Page page = PageHelper.localPage.get();
        if(page!=null){
            page.setCurrentPage(Integer.parseInt(currentPage));
        }
        PageHelper.endPage();
 
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", 0);
        jsonObject.put("msg", "");
        jsonObject.put("count", total);
        jsonObject.put("data", list);
        //System.out.println("json:----" + jsonObject.toString());
        return jsonObject.toString();
      }


其中sql在计算总数totle时可以这么写

COUNT(*) OVER(PARTITION BY 1) AS TOTAL





作者:ardo_pass 发表于2017/11/20 20:07:32 原文链接
阅读:0 评论:0 查看评论
Viewing all 35570 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>