北京解讀純電動客車補貼政策

今天(10日)上午,北京市對購買純電動客車有關財政政策進行解讀。北京提供1∶1市級財政補貼,兩級財政補貼總額最高不超過車輛銷售價格的60%。  
補貼範圍   行政事業單位使用財政資金購買純電動客車不納入通知規定的補助範圍。地方純電動客車補貼,直接撥付到汽車生產企業,消費者按銷售價格扣減補助後支付。  
按車長補貼   2015年純電動客車推廣應用補助標準按車長執行,車長超過10米的車補助標準最高,達50萬元 2016年補助標準中引入車長在10米-12米之間的“標準車”概念,在單位載品質能量消耗量小於0.25、續駛里程超過250公里時,補貼金額最多,可達50萬 12米以上、雙層客車參照標準車1.2倍給予補助 8-10米客車,按照標準車0.8倍給予補助 6-8米客車,參照標準車的0.5倍給予補貼 6米及以下客車參照標準車的0.2倍給予補助 2017年補助標準在2016年基礎上下調20%   面向全國開放純電動客車市場,北京市採用備案制管理,只要納入國家《節能與新能源汽車示範推廣應用工程推薦車型目錄》和《免征車輛購置稅的新能源汽車車型目錄》,完成企業和產品備案,即可在京銷售。   凡是滿足交通行業相關規定的運營企業均可購置、運營純電動客車。鼓勵公交、公路客運、旅遊等領域的企業積極開展純電動客車示範推廣工作;積極鼓勵開展各種純電動客車車型示範應用。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

巴西奧運電動車組出廠 中車長客 100 列全數完工

為迎接 2016 年奧運,巴西和中國中車長客股份公司簽約,中國將提供 120 輛電動車組和 114 輛地鐵車輛,長客公司已於 19 日順利交付最後 100 列電動車組。   中新社報導,隨著最後一列電動車組(EMU)19 日在長春下線,由中國中車長客股份公司為巴西里約熱內盧製造的 100 列電動車組全部交付,每列 4 輛編組,最高時速可達 100 公里。這些列車屆時將肩負 2016 奧運交通運輸。  

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!

mpvue+小程序雲開發,純前端實現婚禮邀請函(相冊小程序)

請勿使用本文章及源碼作為商業用途!

前言

當初做這個小程序是為了婚禮前的需要,結婚之後,希望這個小程序能夠留存下來,特地花了一些空閑時間將小程序轉化成為“相冊類小程序”

體驗碼

準備工作

  1. mpvue框架 
  2. 小程序·雲開發 

注意:使用mpvue前,首先你得先熟悉vue框架的基本使用 

項目結構介紹

注意:接下來展示的代碼,有幾個對比,分別是本人優化前和優化后的代碼對比,感興趣的可以着重看一下優化后的成熟寫法。

  • common目錄: 放一些公共資源,如js,css,json
  • components目錄:組件相關的.vue文件都放在這裏
  • pages目錄:所有頁面都放在這個目錄
  • utils目錄:使用mpvue時自動生成,可忽略
  • app.json文件:
{
  "pages": [ "pages/index/main", "pages/photo/main", "pages/map/main", "pages/greet/main", "pages/message/main" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" }, "tabBar": { "color": "#ccc", "selectedColor": "#ff4c91", "borderStyle": "white", "backgroundColor": "#ffffff", "list": [ { "pagePath": "pages/index/main", "iconPath": "static/images/1-1.png", "selectedIconPath": "static/images/1-2.png", "text": "邀請函" }, { "pagePath": "pages/photo/main", "iconPath": "static/images/2-1.png", "selectedIconPath": "static/images/2-2.png", "text": "甜蜜相冊" }, { "pagePath": "pages/map/main", "iconPath": "static/images/3-1.png", "selectedIconPath": "static/images/3-2.png", "text": "酒店導航" }, { "pagePath": "pages/greet/main", "iconPath": "static/images/4-1.png", "selectedIconPath": "static/images/4-2.png", "text": "好友祝福" }, { "pagePath": "pages/message/main", "iconPath": "static/images/5-1.png", "selectedIconPath": "static/images/5-2.png", "text": "留言評論" } ] }, "requiredBackgroundModes": ["audio"] }
  • App.vue文件 (本人主要是為了增加項目更新后的提醒),所以在這個文件加了些相關內容,內容如下:
<script>
export default { onLaunch () { // 檢測小程序是否有新版本更新 if (wx.canIUse('getUpdateManager')) { const updateManager = wx.getUpdateManager() updateManager.onCheckForUpdate(function (res) { // 請求完新版本信息的回調 if (res.hasUpdate) { updateManager.onUpdateReady(function () { wx.showModal({ title: '更新提示', content: '新版本已經準備好,是否重啟應用?', success: function (res) { if (res.confirm) { // 新的版本已經下載好,調用 applyUpdate 應用新版本並重啟  updateManager.applyUpdate() } } }) }) // 小程序有新版本,會主動觸發下載操作(無需開發者觸發)  wx.getUpdateManager().onUpdateFailed(function () { // 當新版本下載失敗,會進行回調  wx.showModal({ title: '提示', content: '檢查到有新版本,下載失敗,請檢查網絡設置', showCancel: false }) }) } }) } else { // 版本過低則無法使用該方法  wx.showModal({ title: '提示', confirmColor: '#5BB53C', content: '當前微信版本過低,無法使用該功能,請升級到最新微信版本后重試。' }) } } } </script> <style lang="stylus"> page height 100% image display block </style>
  • main.js文件:
import Vue from 'vue'
import App from './App' Vue.config.productionTip = false App.mpType = 'app' wx.cloud.init({ env: '雲開發環境ID' }) const app = new Vue(App) app.$mount()
  • functions目錄:主要放一些雲函數,這裏不清楚雲函數的文章後面會提及
  • images目錄:主要放一些靜態資源圖片

頁面介紹

首頁——邀請函

首頁着重和大家講解下背景音樂的實現方法

const audioCtx = wx.createInnerAudioContext()

 接口獲取實例

接着,通過實例的相關方法來實現音樂的播放與暫停功能

具體代碼如下:

<script>
import IndexSwiper from 'components/indexSwiper' import tools from 'common/js/h_tools' const audioCtx = wx.createInnerAudioContext() export default { name: 'Index', components: { IndexSwiper }, data () { return { isPlay: true, list: [] } }, onShow () { const that = this that.isPlay = true that.getMusicUrl() }, methods: { audioPlay () { const that = this if (that.isPlay) { audioCtx.pause() that.isPlay = false tools.showToast('您已暫停音樂播放~') } else { audioCtx.play() that.isPlay = true tools.showToast('背景音樂已開啟~') } }, getList () { const that = this const db = wx.cloud.database() const banner = db.collection('banner') banner.get().then(res => { that.list = res.data[0].bannerList }) }, getMusicUrl () { const that = this const db = wx.cloud.database() const music = db.collection('music') music.get().then(res => { let musicUrl = res.data[0].musicUrl audioCtx.src = musicUrl audioCtx.loop = true audioCtx.play() that.getList() }) } }, onShareAppMessage: function (res) { return { path: '/pages/index/main' } } } </script>

以上代碼中使用到了雲開發相關功能,文章後面會介紹,請大家稍安勿躁

相冊頁——就一個輪播圖,這裏就不過多介紹

地圖頁——這裏着重講一下地圖標籤map

map標籤 

這裏講一下標記點markers:

data () {
    return { // qqSdk: '',  markers: [{ iconPath: '../../static/images/nav.png', id: 0, latitude: 30.08059, longitude: 115.93027, width: 50, height: 50 }] } }
<template>
    <div class="map">
        <image mode="aspectFit" class="head-img" src="../../static/images/t1.png"/>
        <map class="content" id="map" longitude="115.93027" latitude="30.08059" :markers="markers" scale="18" @tap="toNav">
        </map>
        <div class="call">
            <div class="left" @tap="linkHe">
                <image src="../../static/images/he.png"/>
                <span>呼叫新郎</span>
            </div>
            <div class="right" @tap="linkShe">
                <image src="../../static/images/she.png"/>
                <span>呼叫新娘</span>
            </div>
        </div>
        <image class="footer" src="../../static/images/grren-flower-line.png"/>
    </div>
</template>

祝福頁——也是雲開發相關內容,後面會介紹

留言頁——也是雲開發相關內容,後面會介紹

雲開發介紹

project.config.json文件:

"cloudfunctionRoot": "static/functions/"

進行雲開發首先我們需要找到上面這個文件,在上面這個json文件中加上上面這行代碼

cloudfunctionRoot 用於指定存放雲函數的目錄

app.json文件:

"window": {
    "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "WeChat", "navigationBarTextStyle": "black" }, "cloud": true

增加字段 "cloud": true實現雲開發能力的兼容性

開通雲開發

在開發者工具工具欄左側,點擊 “雲開發” 按鈕即可開通雲開發

雲開發控制台

數據庫

 雲開發提供了一個 JSON 數據庫

 

存儲

 

雲開發提供了一塊存儲空間,提供了上傳文件到雲端、帶權限管理的雲端下載能力,開發者可以在小程序端和雲函數端通過 API 使用雲存儲功能。

 

雲函數

 

雲函數是一段運行在雲端的代碼,無需管理服務器,在開發工具內編寫、一鍵上傳部署即可運行後端代碼。

使用雲開發

雲能力初始化

在小程序端開始使用雲能力前,需先調用 wx.cloud.init 方法完成雲能力初始化

import Vue from 'vue'
import App from './App' Vue.config.productionTip = false App.mpType = 'app' wx.cloud.init({ env: '雲開發環境ID' }) const app = new Vue(App) app.$mount()

數據庫的使用

在開始使用數據庫 API 進行增刪改查操作之前,需要先獲取數據庫的引用。以下調用獲取默認環境的數據庫的引用:

const db = wx.cloud.database()

 要操作一個集合,需先獲取它的引用:

const todos = db.collection('todos')

操作數據庫的相關示例

例:首頁獲取背景音樂資源

getMusicUrl () {
      const that = this const db = wx.cloud.database() const music = db.collection('music') music.get().then(res => { let musicUrl = res.data[0].musicUrl audioCtx.src = musicUrl audioCtx.loop = true audioCtx.play() that.getList() }) }

 例:首頁獲取輪播圖數組

getList () {
      const that = this const db = wx.cloud.database() const banner = db.collection('banner') banner.get().then(res => { that.list = res.data[0].bannerList }) }

例:祝福頁,用戶送上祝福存儲用戶

<script>
import tools from 'common/js/h_tools' export default { name: 'Greet', data () { return { userList: [], openId: '', userInfo: '' } }, onShow () { const that = this that.getUserList() }, methods: { scroll (e) { console.log(e) }, sendGreet (e) { const that = this if (e.target.errMsg === 'getUserInfo:ok') { wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo that.getOpenId() } }) } }, addUser () { const that = this const db = wx.cloud.database() const user = db.collection('user') user.add({ data: { user: that.userInfo } }).then(res => { that.getUserList() }) }, getOpenId () { const that = this wx.cloud.callFunction({ name: 'user', data: {} }).then(res => { that.openId = res.result.openid that.getIsExist() }) }, getIsExist () { const that = this const db = wx.cloud.database() const user = db.collection('user') user.where({ _openid: that.openId }).get().then(res => { if (res.data.length === 0) { that.addUser() } else { tools.showToast('您已經送過祝福了~') } }) }, getUserList () { const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) } } } </script>

獲取送祝福的好友列表

getUserList () {
      const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) }

這裏用到了雲函數,之所以用雲函數是因為小程序端在獲取集合數據時服務器一次默認並且最多返回 20 條記錄,雲函數端這個数字則是 100。

雲函數的使用方法

上面我們講過在project.config.json文件中配置雲函數存放位置

下面是雲函數messageList的index.js文件:

不成熟寫法:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() const MAX_LIMIT = 100 exports.main = async (event, context) => { // 先取出集合記錄總數 const countResult = await db.collection('message').count() const total = countResult.total // 計算需分幾次取 const batchTimes = Math.ceil(total / 100) // 承載所有讀操作的 promise 的數組 const tasks = [] for (let i = 0; i < batchTimes; i++) { const promise = db.collection('message').skip(i * MAX_LIMIT).limit(MAX_LIMIT).get() tasks.push(promise) } // 等待所有 return (await Promise.all(tasks)).reduce((acc, cur) => ({ data: acc.data.concat(cur.data), errMsg: acc.errMsg })) }

成熟寫法(分頁查詢):

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const dbName = 'message' const filter = event.filter ? event.filter : null const pageNum = event.pageNum ? event.pageNum : 1 const pageSize = event.pageSize ? event.pageSize : 10 const countResult = await db.collection(dbName).where(filter).count() const total = countResult.total const totalPage = Math.ceil(total / pageSize) let hasMore if (pageNum >= totalPage) { hasMore = false } else { hasMore = true } return db.collection(dbName).orderBy('time', 'desc').where(filter).skip((pageNum - 1) * pageSize).limit(pageSize).get().then(res => { res.hasMore = hasMore res.total = total res.openId = wxContext.OPENID return res }) }

使用雲函數前,在開發者工具上,找到messageList目錄,右鍵如圖:

 點擊上傳並部署:雲端安裝依賴(不上傳node_modules)

得到如圖的提示:

 安裝完點擊完成就能使用當前雲函數了,使用方法即:

getUserList () {
      const that = this wx.cloud.callFunction({ name: 'userList', data: {} }).then(res => { that.userList = res.result.data.reverse() }) }

數組之所以要倒序是因為希望新祝福的的用戶在最前面显示 

用戶送上祝福的時候存儲用戶

這裏我們用到了雲函數獲取用戶信息,

當小程序端調用雲函數時,雲函數的傳入參數中會被注入小程序端用戶的 openid,開發者無需校驗 openid 的正確性,因為微信已經完成了這部分鑒權,開發者可以直接使用該 openid

不成熟寫法:

下面是雲函數user的index.js文件:

// 雲函數入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 雲函數入口函數
exports.main = async (event, context) => { const wxContext = cloud.getWXContext() return { event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID } }

主要是為了獲取當前操作用戶的openid,獲取當前用戶的openid方法:

getOpenId () {
      const that = this wx.cloud.callFunction({ name: 'user', data: {} }).then(res => { that.openId = res.result.openid that.getIsExist() }) }

接着判斷當前用戶是否已經存在於數據庫中,即getIsExist()方法:

getIsExist () {
      const that = this const db = wx.cloud.database() const user = db.collection('user') user.where({ _openid: that.openId }).get().then(res => { if (res.data.length === 0) { that.addUser() } else { tools.showToast('您已經送過祝福了~') } }) }

如果得到的數組長度為零則添加改用戶到數據庫,否則則提醒當前用戶已經送過祝福

接下來介紹存儲用戶信息的方法,即addUser():

addUser () {
      const that = this const db = wx.cloud.database() const user = db.collection('user') user.add({ data: { user: that.userInfo } }).then(res => { that.getUserList() }) }

存入到數據庫的信息是這樣的:

成熟寫法(使用雲函數一次搞定):

// 雲函數入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database() exports.main = async (event, context) => { const wxContext = cloud.getWXContext() const dbName = 'user' const filter = { _openid: wxContext.OPENID } const countResult = await db.collection(dbName).where(filter).count() const total = countResult.total if (total) { return { has: true } } else { return db.collection(dbName).add({ data: { user: event.user, _openid: wxContext.OPENID, time: db.serverDate() } }) } }
toMessage (e) {
      const that = this
      if (e.target.errMsg === 'getUserInfo:ok') { wx.getUserInfo({ success: function (res) { that.userInfo = res.userInfo wx.navigateTo({ url: `/pages/writeMessage/main?avatar=${that.userInfo.avatarUrl}&name=${that.userInfo.nickName}`  }) that.addUser(that.userInfo) } }) } }, addUser (obj) { wx.cloud.callFunction({ name: 'addUser', data: { user: obj } }) }

總結 

大概的功能就是這麼多,希望可以幫助到大家,覺得寫得不錯的記得給作者點個贊,你們的支持是我不斷更新的最大動力!

源碼地址

後續優化

  • 留言審核
  • 一些動畫效果
  • 分頁處理
  • 雲函數優化
  • 回到頂部

最後

一開始不清楚隨筆和文章的區別,還是希望這篇隨筆能展示在博客園首頁(所以改成隨筆),讓更多的朋友看到

希望對那些有想法又不會後台開發的朋友一些啟示作用,祝你早日做出只屬於自己的小程序。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

實現 sqrt(x):二分查找法和牛頓法

最近忙裡偷閑,每天刷一道 LeetCode 的簡單題保持手感,發現簡單題雖然很容易 AC,但若去了解其所有的解法,也可學習到不少新的知識點,擴展知識的廣度。

創作本文的思路來源於:

簡述題目大意(不想跳轉鏈接,可以看這裏):給定一個非負整數 x,要求計算並返回 x 的平方根(取整)。例如,輸入 4,則輸出 2;輸入 8,則輸出 2(8 的平方根是 2.82842……,由於返回類型是整數,因此小數部分被捨去)。即給定一個 \(x\),我們要計算出 \(\lfloor \sqrt{x} \rfloor\)

最簡單最直覺的方法自然是從 0 開始遍歷,直到找到第一個其平方值大於 \(x\) 的數 \(n\),則 \(n-1\) 即是答案。對於任意的 \(x\),其取整后平方根一定在 \([0, x]\) 區間上,代碼如下:

int sqrt(int x)
{
    if (x == 0)
        return x;
    int ans = 1;
    while (ans <= x / ans)
        ans++;
    return ans - 1;
}

這裏需要注意的有兩點:

  1. 第 6 行代碼中,while 的判斷條件可以避免溢出。很大概率上,你可能會寫成 while (ans * ans <= x),這更自然、更直觀,但當 ans 的值很大時,ans * ans 的結果可能會超過 int 類型的最大表示範圍。舉個例子,比如我們要計算 \(x\) 的取整平方根(其值為 \(n\),即 \(\lfloor \sqrt{x} \rfloor = n\)),算法會將 ans 遍歷到第一個平方超過 \(x\) 的值,即 \(n+1\) 后停止。如果 \(x\) 的值就是 int 類型能夠表示的最大值,那麼當 ans 遍歷到 \(n+1\) 時,計算 ans * ans 的結果就超出了 int 類型的表示範圍。
  2. 由於在 while 的循環判斷中,我們用除法代替了乘法,因此 ans 便不能再從 0 開始遍歷(否則會導致除零錯誤)。為此,我們可以在算法開始單獨處理 \(x = 0\) 的情況,然後讓 ans 從 1 開始遍歷。

作為一道簡單題,這種暴力樸素的算法自然是可以 AC 的。但其效率極低(需要遍歷 \(O(\sqrt{n})\) 次),在 LeetCode 上的時間效率只能快過約 5% 的用戶,使用 C++ 語言的運行時間平均要 90ms 以上。因此,本文提供了兩種更加高效的算法:二分查找法和牛頓法。

1. 二分查找法

如果你在暴力求解的基礎上繼續思考,很大概率會想到用二分搜索求解。

沒錯,思考暴力求解的策略,我們在區間 \([0, x]\) 上搜索解,而搜索區間 \([0, x]\) 天然是有序的,自然可以用二分搜索代替線性搜索,以大大提高搜索效率。

更進一步的,我們還可以縮小我們的搜索區間。直覺告訴我們,對於一個非負整數 \(x\),其 \(\sqrt{x}\) 應該不會大於 \(x / 2\)(例如,\(\sqrt{25} = 5\),小於 \(25 / 2 = 12.5\))。我們可以證明:

\[ \begin{aligned} &\text{設 } y = \frac{x}{2} – \sqrt{x},\text{ 則 } y^\prime = \frac{1}{2} – \frac{1}{2\sqrt{x}}, \\[2ex] &\text{令 } y^\prime = 0, \text{ 可得駐點 } x = 1, \\[2ex] &\text{當 } x > 1 \text{ 時}, y^\prime > 0, \text{ 即當 } x > 1 \text{ 時 }, y = \frac{x}{2} – \sqrt{x} \text{ 的值單調遞增}, \\[2ex] &\text{可推出, 當 } x > 1 \text{ 時}, \lfloor \frac{x}{2} \rfloor – \lfloor \sqrt{x} \rfloor \text{ 的值單調遞增}, \\[2ex] &\text{又因為當 } x = 2 \text{ 時}, \lfloor \frac{x}{2} \rfloor – \lfloor \sqrt{x} \rfloor = 0, \\[2ex] &\text{所以當 } x \geq 2 \text{ 時}, \lfloor \frac{x}{2} \rfloor – \lfloor \sqrt{x} \rfloor \geq 0, \text{ 即 } x \geq 2 \text{ 時},\lfloor \frac{x}{2} \rfloor \geq \lfloor \sqrt{x} \rfloor &\text{(證畢)} \end{aligned} \]

通過證明我們可以得知,當所求的 \(x\) 大於等於 \(2\) 時,sqrt(x) 的搜索空間為 \([1, x / 2]\),對於 \(x < 2\) 的情況,我們只要特殊處理即可(這裏我們也可以得到結論:當 \(x \geq 1\) 時,\(\lfloor \frac{x}{2} \rfloor + 1 \geq \lfloor \sqrt{x} \rfloor\),然後單獨處理 \(x < 1\) 的情況)。代碼:

int sqrt(int x)
{
    if (x < 2)  // 處理特殊情況
        return x;
    
    int left = 1, right = x / 2;
    while (left <= right) {
        # 避免溢出,相當於 mid = (left + right) / 2
        int mid = left + ((right - left) >> 1);
        if (mid == x / mid)
            return mid;
        else if (mid > x / mid)
            right = mid - 1;
        else
            left = mid + 1;
    }
    return right;
}

在這裏解釋一下最後的返回值為什麼是 right。對於二分查找,其搜索空間會不斷收縮到 left == right(關於二分查找,這裏不多贅述,自行手動模擬即可),此時 midleftright 三者的值相等(mid = (left + right) / 2)。根據二分查找的搜索範圍的收縮條件可知,left(或 mid)左側的值都小於等於 \(\lfloor \sqrt{x} \rfloor\)right(或 mid)右側的值都大於 \(\lfloor \sqrt{x} \rfloor\),此時(while 的最後一次循環),判斷 mid 的平方與 x 的大小,有三種情況:

  1. mid == x / mid。則在循環內直接返回 mid 的值。
  2. mid > x / mid。這種情況下,因為 mid 左側的值都小於等於 \(\lfloor \sqrt{x} \rfloor\),而 mid 的值大於 \(x\),則 mid-1 即是答案。而按照分支條件,執行 right = mid - 1,可知 right 的值正是應返回的值。此時,循環結束,應返回 right
  3. mid <= x / mid。這種情況下,midleftright 正是計算答案(右邊的值都大於 \(\lfloor \sqrt{x} \rfloor\))。按照分支條件,執行 left = mid + 1,循環結束。此時,midright 的值為計算結果。

綜合上面三點可知,如果 while 循環結束,則 right 保存的值一定是計算結果。

和之前的暴力法相比,使用二分查找的思想求解 sqrt(x),只需要循環遍歷 \(O(\lg{\frac{x}{2}})\) 次;空間複雜度為 \(O(1)\)

2. 牛頓—拉弗森迭代法

牛頓—拉弗森迭代法(簡稱牛頓法)使用以直代曲的思想,是一種求解函數的方法,不僅僅適用於求解開方計算。當然使用牛頓法求解函數也存在很多坑,但對於求解開方而言,牛頓法是安全的。關於這一方法,你需要掌握一定的高等數學知識,想了解詳細的內容,可以參考鏈接:

簡單的理解,可以參考圖片:

圖片來源:

給定任意一個非負整數 \(n\),我們想要找到一個 \(x = \lfloor \sqrt{n} \rfloor\),這相當於我們要計算函數 \(f(x) = x^2 – n\) 的根。我們首先需要先給出一個猜測值 \(x_0\),不妨令 \(x_0 = \frac{x}{2} + 1\)(證明見第一小節),然後在 \(f(x_0)\) 處作函數的切線,切線與 \(x\) 軸的交點,即為一次迭代后的值 \(x_1\)。若 \(x_1\) 不是要得到的結果,則繼續迭代,在 \(f(x_1)\) 處作函數的切線,切線與 \(x\) 軸的交點,即為第二次迭代后的值 \(x_2\)。以此類推,直到得到 \(x_n = \lfloor \sqrt{n} \rfloor\)

現在我們來推導迭代式。對於 \(x_i\),其函數值為 \(f(x_i)\),則對於點 \((x_i, f(x_i))\),可得其切線方程:

\[ \begin{align} &y – f(x_i) = f(x_i)^\prime(x – x_i) \\[2ex] \implies &y – (x_i^2 – n) = 2x_i(x – x_i) \\[2ex] \implies &y + x_i^2 + n = 2x_ix \end{align} \]

又因為 \(x_{i+1}\) 為切線與 \(x\) 軸的交點,所以令 \(y=0\),可得:

\[ x_{i+1} = (x_i + n / x_i) / 2 \]

現在,我們就可以根據迭代式編寫代碼了:

int sqrt(int x)
{
    // 避免除零錯誤,單獨處理 x = 0 的情況
    if (x == 0)
        return x;
    int t = x / 2 + 1;
    while (t > x / t)
        t = (t + x / t) / 2;
    return t;
}

為了確保算法是正確的,我們還需要一些額外的證明。首先,證明迭代式是單調遞減的:

\[ x_{i+1} – x_i = \left\lfloor \frac{1}{2} (x_i + \frac{n}{x_i}) \right\rfloor – x_i = \left\lfloor \frac{1}{2} (\frac{n}{x_i} – x_i) \right\rfloor \]

可知,在區間 \([\sqrt{x}, +\infty)\) 上,\(x_{i+1} – x_i < 0\)

然後,我們還要證明迭代式是可以收斂到 \(\lfloor \sqrt{n} \rfloor\) 的:

\[ x_{i+1} = \left\lfloor \frac{1}{2} \left( x_i + \left\lfloor \frac{n}{x_i} \right\rfloor \right) \right\rfloor = \left \lfloor \frac{1}{2} (x_i + \frac{n}{x_i}) \right \rfloor \geq \left \lfloor \frac{1}{2} \times 2 \times \sqrt{x_i \cdot \frac{n}{x_i}} \right \rfloor = \lfloor \sqrt{n} \rfloor \]

因此,當 while 循環結束時,我們可以得到正確的答案。

關於牛頓法求 sqrt(x) 的時間複雜度,筆者目前也沒有搞清楚,有了解的童鞋歡迎交流~。不過通過查詢資料,以及實際測試,可知牛頓法的時間效率優於二分搜索法。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!

湖北禁用廚餘垃圾餵豬 違規可罰5萬元

摘錄自2020年1月7日星島日報報導

中國非洲豬瘟疫情持續,湖北省政府立法,直接使用廚餘垃圾餵豬,將罰款最高5萬元人民幣,將於3月1日起實施。

政府指,為加強廚餘垃圾管理,保障食品安全,促進廚餘垃圾資源化利用和無害化處理,所以實施《湖北省餐廚垃圾管理辦法》規定。根據規定,在廚餘垃圾投放、收集、運輸、處置過程中,不得實施下列行為:將廚餘垃圾與其他生活垃圾混合投放;將廚餘垃圾排入污水排水管道、雨水管道等市政公共設施以及河道、湖泊、水庫等公共水域;隨意傾倒、拋撒廚餘垃圾等。

另外亦規定直接使用廚餘垃圾餵豬的,由縣級以上政府農業農村主管部門責令停止違法行為,可以處5000元以上2萬元以下罰款;情節嚴重的,處2萬元以上5萬元以下罰款。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

新疆哈密市爆牛O型口蹄疫 同批64牛遭一併撲殺

摘錄自2020年1月7日星島日報報導

農業農村部新聞辦公室今(7日)發佈,接獲到中國動物疫病預防控制中心報告,指維吾爾自治區哈密煙墩動植物聯合檢查站查獲,一批由河北省保定市曲陽縣調往新疆的牛,部份牛隻出現疑似口蹄疫症狀。

經國家參考實驗室確診為O型口蹄疫疫情。該批牛共64隻,其中兩隻發病。在疫情發生後,當地按照有關預案和防治技術規範要求,切實做好疫情處置工作,發病的牛隻與同群牛已被撲殺及無害化處理,該批牛的調出地亦已展開全面排查和緊急監測工作。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!

傳蘋果電動車將於 2019 年問世

蘋果公司生產汽車傳聞已久,美國《華爾街日報》21 日報導,蘋果正全力研發電動車,希望在 2019 年問世。   報導指出,蘋果電動車計劃的代號為「泰坦」(Titan),車款類型則像廂型休旅車。蘋果除了已聘請無人駕駛領域的專家外,也將泰坦的開發團隊由 600 人擴大 3 倍至 1,800 人,且可能會與傳統車廠合作,但蘋果官方發言人,拒絕對此消息作出評論。   外媒 AppleInsider 上周曾指出,蘋果已向電動車生產商特斯拉招兵買馬。 雖然有報導稱蘋果聘請無人駕駛領域的專家,但首款汽車仍需人操控駕駛。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

Gogoro全系列降價 電池交換站擴至桃竹

台灣電動機車Gogoro上市至今已售出近千輛Smartscooter™智慧機車。10月1日,Gogoro Lite平價版正式推出,售價新台幣62,000元起。此外,電池交換站也將布點至桃園、新竹,讓更多騎士享受Gogoro服務。

Gogoro目前在雙北地區共有七個銷售站、四個維修中心,GoStation電池交換站超過80座,且將走出台北、新北市,將服務擴大到桃園與新竹地區,預計2015年底前就能服務到北北基、桃、竹的騎士。

Gogoro同時發表了廉價版電動機車Gogoro Lite,採用單色儀表板、黑色龍頭按鈕、一般烤漆設計,以及都會型的動力模式;扣除政府補助後的價格為新台幣62,000元起(補助前零售價88,000)。Gogoro以及Gogoro Plus的價格也同步調降到新台幣72,000與82,000元起(補助前零售價分別為98,000及108,000),且九月30日前購買的車主將可全額退還購買差額。

Gogoro創辦人暨執行長陸學森表示:「為進一步滿足多元的需求,讓更多喜歡Gogoro 的朋友也可以輕鬆地成為Smartscooter™ 的車主,我們不僅推出入門款Gogoro® Lite,也同步調整Gogoro® 和Gogoro® Plus 的產品價格,希望消費者在二輪市場主流價格帶有更多、更好的選擇,並透過實際擁有Gogoro®,享受智慧綠能移動的新價值,加速邁入智慧城市的嶄新時代。」

(照片來源:Gogoro)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!

中國成立電動汽車充電基礎設施促進聯盟,解決電動汽車充電難問題

12日,國家能源局會同有關部門在江蘇省常州市組織召開全國電動汽車充電基礎設施促進聯盟成立暨建設經驗交流現場會,宣佈國家電動汽車充電基礎設施促進聯盟正式成立。   據新華社消息,近年來,中國當前充電設施發展仍然存在認識不統一、配套政策不完善、協調推進難度大、標準規範不健全等問題。為此,國家明確提出,到2020年要完成為500萬輛電動汽車配套建設相應規模的充電基礎設施的任務目標。   “大力推進電動汽車充電基礎設施建設,有利於解決電動汽車充電難題,對於打造大眾創業、萬眾創新和增加公共產品、公共服務“雙引擎”,實現穩增長、調結構、惠民生具有重要意義。”國家能源局副局長鄭柵潔介紹。

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※帶您來了解什麼是 USB CONNECTOR  ?

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

第六屆中國國際新能源汽車論壇

第六屆中國國際新能源汽車論壇2016重磅回歸,打造行業規模最大的新能源汽車論壇

2016年4月20-22日∣中國•上海
誰能智造未來-技術應用與新熱點

隨著全球能源危機的加重及汽車排放引起的環境問題日益得到世界各國的重視,發展環保節能的汽車已經成為全球汽車行業的必然趨勢。

在過去五屆新能源汽車論壇成功舉辦的基礎上,由希邁商務諮詢(上海)有限公司主辦的2016年第六屆中國國際新能源汽車論壇即將於4月20日-4月22日在上海隆重舉行。新能源汽車系列論壇成功邀請了包括國家發改委能源研究所、世界電動車協會、亞太電動車協會、世界氫能協會、世界分散式能源聯盟、中國工程院等在內的政府單位與研究機構,以及包括寶馬、賓士、奇瑞捷豹路虎、大眾、奧迪、比亞迪、上汽、北汽等在內的知名整車商,共同研討新能源汽車行業政策趨勢、技術路線及難點、基礎設施建設、商業模式等並取得了豐碩的成果,獲得了業內外人士的一致好評。

在即將到來的2016年,組委會為感謝業內外人士對系列論壇長期以來的支援和關注,將傾情奉上相比歷屆舉辦規模最大的第六屆新能源汽車論壇,涉及三個考察活動,主論壇及三個分論壇。屆時將誠邀全球範圍內的整車製造商、電網電力公司、電池廠商、零部件供應商、核心技術提供商和政府官員近500位行業人士一起,對新能源汽車產業面臨的挑戰,機遇與對策各方面進行為期三天更深層次並具有建設和戰略性的探討。

部分往屆評論

曹俊,奇瑞捷豹路虎
發言角度全面,觀點很多,回饋激烈!

黃錚,上海申沃客車
傳統零配件的演講很好的闡述了供應商如何應對新能源發展的機遇!

洪英林,德爾福
論壇水準很好,很希望下次可以繼續來參會,收穫頗多!

飯田和正,三菱汽車
安排有序,資訊傳達豐富,,演講氣氛非常好!

Thomas PETERS,寶馬中國
組織有序,討論話題很好,演講內容影響深刻!

Robert Galyen, CATL
專業的製造業板塊,內容涵蓋了中國新能源汽車整個產業鏈,十分值得參與!

會議亮點

  • 豐富的內容:
    8大板塊的深度解析
  • 參會嘉賓:
    500+高度滿意的企業決策者,120+業內知名企業,30+國家和地區
  • 參會嘉賓分析:
    17%+來自各國政府部門及權威機構,25%+來自知名整車商
  • 演講嘉賓:
    40+世界新能源汽車行業知名發言嘉賓
  • 交流機會:
    16+小時的交流機會:圓桌討論、VIP午宴和開放式問答
  • 會議形式:
    1個主論壇,1個晚宴,3個分論壇以及一天3個考察活動

會議結構

  上午 下午
 4月20日
  主論壇  
1.新能源汽車政策

2.國內外商業模式探討及專案解析

3.新能源汽車與環保

4.晚宴

4月20日
分論壇一
1.汽車與互聯網    2.汽車O2O

 4月21日
分論壇二           

.動力電池與電池管理系統

2.新能源汽車充電基礎建設與標準

3.無線充電技術

 4月21日
  分論壇三
1.電控電機技術 2.智慧製造產業
考察活動
4月22日

1.參觀上海大眾安亭汽車廠

2.參觀上海燃料電池汽車動力系統有限公司(待定)

3.參觀EV ZONE 中國(上海)電動汽車國際示範城市試駕中心

若您對峰會有更多要求,請撥打021-6045 1760與我們聯繫或登陸官方網站: 連絡人:Hill ZENG(曾先生)
電話:+86 21-6045 1760
傳真:+86 21-6047 5887
郵箱:

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益

※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象

南投搬家前需注意的眉眉角角,別等搬了再說!