2018年9月18日 星期二

Algorithm :: Fisher–Yates shuffle

給定一個數列,要輸出隨機排列的序列:
方法1. c++提供 next_permutation()
http://www.cplusplus.com/reference/algorithm/next_permutation/



















結果:











方法2. 逐一從input array中隨機挑一個複製到output array並且刪掉原本的element
缺點:如果input array是vector,erase會很花時間,而且每次隨機挑選都要重新跑rand(),很耗

方法3. Fisher Yate's Algorithm
https://gaohaoyang.github.io/2016/10/16/shuffle-algorithm/
https://www.cnblogs.com/zichi/p/Fisher-Yates-shuffle.html

假設input array的size = n,index = 0:n1
for( i = n-1: 1){
    隨機產生[0:i]的數字j,把input[i]和input[j] 交換
}

有點像蓄水池理論,要證明就一個一個證,index = 0 的這個element直到最後都沒有被換到的機率是1/n




2018年8月19日 星期日

Algorithm :: Montone queue


Inspire by Leetcode #239
https://leetcode.com/problems/sliding-window-maximum/description/

The purpose is the maintain a queue (FIFO) and get the maximum(or minimum) at any moment in time complexity O(1)

Using two queue (dequeue in c++)
one is normal queue, with FIFO, another is the queue maintains the maximum so far (max queue)

when push(x):
        normal_queue: push_back(x)
        max_queue: pop() all back element until the back element is larger than x (or the queue is empty), and push_back(x)

when pop():
        normal_queue: pop_front() (tmp = front(); pop_front() )
        max_queue: if the front of max_queue is tmp, pop_front(). Else, do nothing
        ( means this maximum element is leaving the queue, time to change to the second largest element)

Take the problem in leetcode for example:




2018年7月30日 星期一

Angular2 Learning Note (4):How to control div style through Angular2


1. Assign backgroud image
Use [style.xxx] directly
<div class="Layout" [style.background-image]="backgroundImg">
</div>

Meet error message: something like trust issue

Add this into app.component.ts
this.backgroundImg = this.sanitizer.bypassSecurityTrustStyle('url(' + this.IndoorLayoutPath + ')');





Check detail in
https://stackoverflow.com/questions/34875426/how-to-add-background-image-using-ngstyle-angular2/34875479

2. To adjust the location of div
<div *ngFor="let rList of RoomList" (click)="assignFacility(rList.name, rList.facility._id, rList.facility.name)">
    <div class="RoomInLayout" *ngIf="rList.facility.name==fList.facility.name"[style.top.px]="rList.x" [style.left.px]="rList.y">
        >{{rList.name}} [x,y]=[ {{rList.x}} ,{{rList.y}}]
    </div>
</div>







2018年7月28日 星期六

Angular2 Learning Note (3):Drag and Drop + Pop up windows + Canvas + File upload


- drop-and-drop:
    https://www.npmjs.com/package/ng2-dnd

有人的demo:
    https://github.com/akserg/ng2-dnd/blob/master/demo/src/app/examples/dnd/simple/simple.component.ts
    http://akserg.github.io/ng2-webpack-demo/#/dnd

我們的:












View:













- pop-up window:
用modal
記錄一下怎麼傳遞參數的
舉例來說:點擊一個stage button的時候會有一個pop-up window,我們想要在這個window裡面讓使用者輸入name和duration,點擊ok的時候回傳到main page
Define一個新的class,view用外部的html















然後再class裡面定義 @Input是從main page要輸入的參數,@Output是要從這個modal輸出到main page的參數






































Input的部分相對簡單,注意我們的Output 是一個EventEmitter() ,我們會在main page中 subscribe這個 EventEmitter





























這裡我們subscribe了兩個在modal中宣告的EventEmitter,都有各自的用途,一個用來update stage configuration,一個用來刪掉stage

另外注意這些pop up window的class都要在 module.ts裡面加入

















- Canvas
在圖片上面用滑鼠拖曳選取範圍:
參考這個
https://stackoverflow.com/questions/47879692/angular2-draw-rectangle-on-canvas-with-mouse?rq=1
html宣告:


Typescript 宣告:

使用(mousedown) (mouseup) (mouvemove) event + drawImage + setLineDash 在canvas上面畫畫



























- ng2-file-upload
https://valor-software.com/ng2-file-upload/

https://ciphertrick.com/2016/10/24/file-upload-with-angular2-nodejs/
https://appdividend.com/2018/05/25/angular-6-file-upload-tutorial/
file的屬性:
https://stackoverflow.com/questions/46703218/ng2-file-upload-does-not-save-original-file-name

本來用的好好得,上傳到assets之後angular2沒辦法讀取他
(好像是因為$ng serve的時候,$ng build 會把assets的內容複製到整個專案當成static context,之後assets內的更新不會被看到,直到手動重新$ng build)
如果只是要上傳檔案可以用
    這個 https://appdividend.com/2018/05/25/angular-6-file-upload-tutorial/
    在html中的宣告:
    
    在type script中的宣告:

    要上傳的時候:
     在 server side:

但是上傳之後要拿url來當作background image source很困難
改用上傳firebase並且擷取url
https://angularfirebase.com/lessons/angular-file-uploads-to-firebase-storage/
https://www.youtube.com/watch?v=4vgrEByJjck
https://github.com/angular/angularfire2/blob/master/docs/install-and-setup.md
http://www.ucamc.com/e-learning/computer-skills/294-upload-files-to-firebase-storage-using-javascript.html
收費:
https://firebase.google.com/pricing/

0. 先把firebase中提供的web application embedded code 複製到Angular的environment參數


















1. 安裝套件並且import module
$npm install angularfire2 firebase --save












2. 在html中使用





在selectedFileOnChanged()中直接把檔案上傳,使用.put() 上傳檔案以及request url
(網路上有一些擷取url的API,這裡我們上傳的時候直接extract:
https://stackoverflow.com/questions/38523515/function-that-returns-download-url-from-firebase-storage
https://stackoverflow.com/questions/43911080/return-the-download-url-of-a-file-uploaded-to-firebase
)































(如果url確定沒錯卻遇到403,去編輯firebase裡面Storage的Rule: 改成all true)






2018年7月22日 星期日

Angular2 Learning Note (2):Basic idea: (Add new component/ Add new services/ @Inject/ @Input/ @Outpu/ Two-way Binding)


(1) Create a new angular project by $ng new hello


$cd hello and start it with $ng serve -o (-o means open it with default browser)
This hello application should listen on http://localhost:4200/
For example, if you change the title variable in app.component.ts, the context in app.component.html will follow up
(you should see the server detect your change and re-start)

(2) Create a new component by $ng generate component simple-form (which equals with $ng g c simple-form)
You can use $ng g c simple-form --inline-template --inline-style (which can be shorter, $ng g c simple-form -it -is).
The two options will put your .html and .css into the Typescript file, nothing very special. We use $ng g c simple-form here.

Check src/app/simple-form.component.ts, this describes your component. App-simple-form is the directive name you can use in the view.
Modify the context of src/app.component.html. Delete some redundancy context.
As you can see, the context of simple-form is added into our view

(3) Events and Reference
Add the following code into src/app/simple-form/simple-form.component.html
And add the following code into src/app/simple-form/simple-form.component.ts.
When the button is click (or mouseover, it pass the $event and the value of #myInput to onClick() function)
Open console of your browser to see the console.log output (cmd+option+k in mac)

(4) Dependency Injection
Create a service by $ng g s mail (in complete: $ng generate service mail)
And add to provider in src/app/app.module.ts (Remember to import)
    ( There is another syntax supporting, list here)
And add this service in constructor in src/app/app.component.ts (Also remember to import)
    ( Another syntax using inject lists here)
Since we already inject this service into app. Add a array message in src/mail.service.ts
And use this in app.component.html

(5) ngFor
Add the following code to src/app.component.html.
And see the result

(6) @Input/ @Output
@Input and @Output are two method to pass parameter between two components.
It is easier if two components are parent<->child, but passing between two sibling components is still doable.
We use a parent component <app-root> and child component <app-simple-form> as example
In order to pass parameter from root to simple-form.
    (1) Declare a @Input [variable] in the receiver component and use it in the view
    (2) pass this parameter in the html tag in parent component
    (ex: [variable] = … )
And you may see the context in child component is based on parent component
In order to pass parameter from from simple-form to root.
(1) Declare a @Output [variable] in simple-form component, means we are going to pass this parameter out-ward
In the button, add (click)=”variable.emit(message)”. The eventemitter will send it when we click the button
(2) Add (update)=”onUpdate()” in app component as receiver from simple-form component and call the method provided in mail service
(3) Change the value stored in mail service
(7) Two-way binding:
Angular provides [(ngModel)] to implement two-way-binding, which is monitor the specific variable.
The two-way is the combination of ( )->event and [ ]->pass_value_in.
When the value is changed in this component, ()->event will pass the value out, when the value is changed from outside, []->pass_value_in will pass the value out.
The placeholder in input box will be initialized as mail.message. But when you modified the value, it will change the source simultaneously.

Notice: you may see the error message if you just add [(ngModel)] to your program.
This is because of https://stackoverflow.com/questions/38892771/cant-bind-to-ngmodel-since-it-isnt-a-known-property-of-input
For using [(ngModel)] in Angular 2, 4 & 5+, You need to import FormsModule from Angular form...


Reference:
[1] EggHead