Học máy là gì?

Định nghĩa

Với trí tuệ nhân tạo cổ điển, khi mà muốn máy tính hoàn thành một nhiệm vụ thì lập trình viên phải chỉ rõ trong code (mã nguồn) cách thực hiện nhiệm vụ đó như thế nào. Trong khi đó ML, nói một cách đơn giản là tập hợp của những phương pháp giúp cho máy tính có thể học được cách thực hiện những nhiệm vụ đó mà không cần sự chỉ dẫn trực tiếp của con người (Arthur Samuel, 1959).

Những bài toán được giải quyết bởi ML thường là

Những bài toán có quy mô lớn như việc xử lí dữ liệu web, dữ liệu đa phương tiện (multimedia), dữ liệu từ cảm biến (sensors), …
Những bài toán quá phức tạp mà chúng ta không biết lời giải dạng hiện (closed form solution) hoặc không thể lập trình bằng tay được như thị giác máy tính (Computer Vision, CV, giúp cho máy tính có khả năng nhận biết thế giới qua hình ảnh tương tự như thị giác con người), xử lí ngôn ngữ tự nhiên (Natural Language Processing, NLP, giúp cho máy tính có khả năng hiểu được ngôn ngữ của con người), điều khiển robot, xe cộ trong môi trường tự nhiên, …
Một số ví dụ cụ thể về bài toán phù hợp với ML như:

Tìm kiếm trên web: hàng ngày chúng ta cần phải tìm rất nhiều thông tin trên web, việc dùng người duyệt qua hàng tỉ trang web để tìm thứ phù hợp là không khả thi. Các thuật toán ML có khả năng tính toán độ phù hợp giữa câu hỏi của người dùng (query) và nội dung của các trang web và sắp xếp chúng theo thứ tự để trả về cho người dùng.
Lọc spam mail: các hệ thống lọc spam cần phát hiện nhưng email có nội dung khác thường và lừa đảo và ngăn chúng tới được inbox của người dùng. Khác biệt với bài toán trên, chúng ta cần phát hiện ra sự bất thường, đo đạc sự khác nhau giữa những email thông thường và spam.
Nhận dạng ảnh: khác với văn bản, khi mà một ý tưởng thường chỉ có một số nhỏ cách diễn đạt và các cách diễn đạt thường sử dụng những từ ngữ giống nhau hoặc đồng nghĩa, ảnh chụp của cùng một vật thể ở mỗi góc độ khác nhau, điều kiện môi trường khác nhau thì có thể rất khác nhau nếu so sánh ở từng điểm ảnh. Các hệ thống xử lí ảnh cần phải nhận ra những đặc trưng bất biến (invariants) trong những bức ảnh để có thể đạt được độ chính xác cao
Định nghĩa: Bài toán ML một chương trình A được gọi là học từ kinh nghiệm E(xperience) để thực hiện một nhiệm vụ T(ask) nếu như hiệu quả thực hiện P(erformance) của nó tăng lên sau khi được bổ sung E.

Huấn luyện và kiểm tra

Quá trình xây dựng một hệ thống ML thường bao gồm hai giai đoạn: huấn luyện và kiểm tra.

Huấn luyện Quá trình dạy một hệ thống ML học gọi là huấn luyện (training). Huấn luyện thường là việc đưa cho hệ thống ML những ví dụ mẫu (training example) và dựa trên những ví dụ đó, hệ thống phải hiệu chỉnh các tham số (parameters) của mình để có thể cho ra được kết quả đúng ở những ví dụ sau. Quá trình hiệu chỉnh tham số thường sử dụng các thuật toán tối ưu (optimization ví dụ convex optimization, linear optimization, …) và quy hoạch (programming, ví dụ dynamic programming, approximate dynamic programming, …) và nhiều phương pháp toán học, thống kê khác.

Kiểm tra Sau khi hoàn thành huấn luyện, hiệu năng (performance) của một hệ thống thường được ước lượng bằng hiệu năng của nó trên một tập dữ liệu kiểm tra (test set) khác với tập huấn luyện (training set). Quá trình này gọi là kiểm tra (testing) nhằm ước lượng hiệu quả thực sự của hệ thống trong môi trường làm việc. Test set bắt buộc phải khác với training set vì hệ thống được huấn luyện trên training set nên nó sẽ dần thích nghi với những đặc điểm của training set và đạt được hiệu năng cao trên tập này, không phản ánh hiệu năng thực tế của hệ thống trong môi trường làm việc.

Sự tương đồng Quá trình training và testing giống như quá trình dạy học và thi cử trong đời sống. Trong quá trình dạy, giáo viên đưa cho sinh viên rất nhiều bài tập và qua quá trình giải các bài tập đó, sinh viên dần hiểu được bản chất của vấn đề. Tương tự như vậy, chúng ta đưa cho hệ thống ML rất nhiều ví dụ và qua các ví dụ đó, hệ thống dần dần xây dựng hiểu biết về bài toán. Thi cử là để đánh giá hiểu biết của sinh viên, nếu giáo viên đưa cho sinh viên những bài toán đã dùng trong quá trình giảng dạy, sinh viên sẽ dễ dàng đạt được điểm cao hơn hiểu biết thực sự của họ về vấn đề. Do đó, bài toán trong đề thi cần phải khác với những bài toán sử dụng trong quá trình dạy học. Năng lực thực sự của sinh viên, giống như hiệu năng hệ thống ML, là những đại lượng ẩn (hidden variables), chúng ta ước lượng nó thông qua thi cử. Đến đây thì có lẽ mọi người đều hiểu rõ vì sao có tên gọi Machine learning. Tuy nhiên, khi dịch sang tiếng Việt là học máy thì nghe không được xuôi tai cho lắm, :v.

Phân loại hệ thống ML

Các hệ thống ML được phân loại theo cách thức mà người ta huấn luyện nó. Một số nhánh chính của học máy bao gồm:

Học có giám sát (Supervised learning, SL)

Phương pháp này được gọi là có giám sát vì trong quá trình huấn luyện, hệ thống ML cần phải biết được câu trả lời chính xác cho mỗi training example. Với mỗi example, hệ thống đo đạc sự khác nhau giữa câu trả lời đúng và câu trả lời mà nó đưa ra. Mục tiêu của training là làm giảm độ sai lệch giữa tập hợp câu trả lời đúng và tập hợp câu trả lời của hệ thống. Mỗi mẫu dùng để huấn luyện bao gồm 2 phần: các đặc trưng để mô tả vật mẫu (features) và nhãn của mẫu (label).

Ví dụ một hệ thống SL dùng để phân loại trái cây thì mỗi training example sẽ có thể có dạng như sau: (màu sắc, vị, cân nặng : tên loại quả), (đỏ, ngọt, 130gram : táo), (vàng, chua, 200gram : cam), … Độ sai khác cho mỗi mẫu là 1 nếu như hệ thống đưa ra câu trả lời sai, 0 nếu câu trả lời đúng. Độ sai khác được tính cho toàn bộ các mẫu trong training set. Huấn luyện nhằm giúp hệ thống đạt được độ sai khác thấp hơn so với lúc ban đầu.

SL thường có hiệu năng cao hơn các phương pháp khác nhưng quá trình huấn luyện tốn kém hơn nhiều do phải gán nhãn cho từng mẫu.

Học không giám sát (Unsupervised learning, UL)

Khác với SL, mục tiêu của UL là học ra những hàm mô tả những cấu trúc ẩn trong dữ liệu. UL nhằm giải quyết những bài toán mà lượng dữ liệu có nhãn là rất ít hoặc không có, hoặc do những đặc trưng của bài toán mà dữ liệu có gán nhãn là không cần thiết.

Ví dụ chúng ta có một lượng lớn khách hàng với những sở thích khác nhau và muốn có một nhân viên hỗ trợ khách hàng cho mỗi nhóm sở thích. Ở đây chúng ta không cần quan tâm sở thích cụ thể của một người là gì mà chỉ muốn những khách hàng có cùng sở thích thì sẽ được hỗ trợ bởi cùng một nhân viên. Chúng ta sử dụng thuật toán phân cụm (clustering), ví dụ như k-means, để nhóm những khách hàng có cùng sở thích lại với nhau dựa theo một độ đo (measure) về sự giống/khác nhau về sở thích giữa 2 người.

Semi-supervised learning (học bán giám sát) là một phương pháp kết hợp giữa UL và SL để giải quyết những bài toán có ít dữ liệu có gán nhãn.

Học tăng cường (Reinforcement learning, RL)

Khác với 2 phương pháp trên, RL không học từ những tập dữ liệu có sẵn mà nó liên quan tới việc điều khiển một/nhiều tác tử (agent) đưa ra những hành động (actions) trong một môi trường (environment) một cách hợp lí để cực đại hóa giá trị phần thưởng tích lũy (cummulative reward).

Ví dụ chúng ta có một robot (agent) với khả năng quan sát hạn hẹp, ở trong một môi trường với nhiều chướng cạm bẫy và phần thưởng. Mục tiêu của robot là tìm ra cách hoạt động thu được nhiều phần thưởng nhất và tránh được các cạm bẫy. Để đạt được điều đó, robot phải trải qua quá trình dò tìm, khảo sát môi trường xung quanh và dần xây dựng nên một mô hình về môi trường đó. Quá trình học này khác với SL, UL vì dữ liệu về môi trường là không sẵn có mà phải được khám phá dần dần qua nhiều lần thử nghiệm.

SL và UL là hai phương pháp phổ biến nhất trong ML nhưng RL cũng là một phương pháp cực kì triển vọng và đang phát triển mạnh mẽ trong thời gian gần đây khi nó được kết hợp với SL và UL.

IOIBIN – spoj

Đề bài:

Thuật toán:

Code:

const   fi = '';
        fo = '';
        maxn = trunc(1e4)+3;
var     p : array[1..maxn] of longint;
        i,j,n,m : longint;
        x,u,v : longint;
procedure chuanbi;
begin
        for i:=1 to maxn do p[i]:=i;
end;
function find(i:longint):longint;
begin
        while p[i]<>i do i:=p[i];
        exit(i);
end;
procedure lam1;
var     i,j : longint;
begin
        i:=find(u);
        j:=find(v);
        if i<>j then
        if i<j then p[j]:=p[i] else p[i]:=p[j];
end;
procedure main;
var     i:longint;
begin
        assign(input,fi);reset(input);
        assign(output,fo);rewrite(output);
        readln(m);
        chuanbi;
 
        for i:=1 to m do
                begin
                        readln(u,v,x);
                        if x=1 then lam1 else
                                if find(u)=find(v) then writeln(1) else writeln(0);
                end;
        close(input);
        close(output);
end;
begin
        main;
end.

Thuật toán sắp xếp tuần tự

Bài toán đặt ra

Cho mảng A gồm n phần tử. Sắp xếp lại dãy A theo chiều giảm dần

Nhập vào: số nguyên dương n và dãy A.

8
9 7 6 15 16 5 10 11
Xuất ra: dãy A sau khi đã được sắp xếp
5 6 7 9 10 11 15 16

Ý tưởng

Tư duy đơn giản như cách chúng ta xếp bài

sap-xep-1-yeulaptrinhHình trên là thao tác xếp cây bài 7 bằng cách rút nó ra và đặt vào vị trí của phù hợp.

Giải sử bài trên tay đang là:

2 5 7 10 4

ta thấy dãy 2,5,7,10 đã tăng dần chỉ còn cây 4 đứng chưa đúng chỗ nên ta đẩy 4 lên trước 10, rồi lên trước 7 cứ như vậy đến khi gặp cây 2 đứng trước. 2 < 4 suy ra thì dừng. Dãy trở thành

2 4 5 7 10

Dãy đã được sắp xếp.

Ý tưởng: duyệt lần lượt từng cây bài, nếu cây bài nhỏ thì ta đẩy dần lên đầu đến khi nào không chuyển lên được nữa

Ví dụ khác:

sap-xep-yeulaptrinh.pwCode:

#include <bits/stdc++.h>

using namespace std;

int n, a[10000];

void doi_cho(int *x, int *y) {
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

int main() {
    cin >> n;
    for (int i=1; i<=n; i++) cin >> a[i];
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<i; j++)
            if (a[j] > a[i])
            {
                doi_cho(&a[i], &a[j]);
            }
    }
    for (int i=1; i<=n; i++) cout << a[i] << " ";
    return 0;
}
Ví dụ:

Với dãy A = {12, 11, 13, 5, 6}

Cho i chạy từ 1 đến 4

i=1. không làm gì cả

12, 11, 13, 5, 6

i = 2. Vì 11 nhỏ hơn 12 nên chuyển 11 lên trước 12
11, 12, 13, 5, 6

i = 3. 13 không cần chuyển lên đầu nữa
11, 12, 13, 5, 6

i = 4. 5 được chuyển chỗ với 13 rồi chuyển chố tiếp lần lượt với 12, 11.
5, 11, 12, 13, 6

i = 5. 6 cũng giông như 5 được chuyển dần lên đến khi gặp 5 nhỏ hơn thì dừng lại
5, 6, 11, 12, 13

Độ phức tạp:

  • O(n^2)

 

Quý bạn đọc có ý kiến, thắc mắc xin comment bên dưới <3

QBRECT – spoj

Đề bài:

Thuật toán:

Sau đây là cách tìm hình chữ nhật lớn nhất trong thời gian O(n^2):

Với mỗi ô j trên hàng i, ta tìm f(j) là số ô 1 liên tiếp trên cột j, tính từ hàng i trở lên. Sau đó, với mỗi cột j, ta tiếp tục tìm ô gần nhất bên trái và ô gần nhất bên phải có f nhỏ hơn f(j), sau đó tính diện tích hình chữ nhật ở cột j là S=f(j)×(r−l−1) với l,r là chỉ số 2 ô bên trái và bên phải nói trên.
Hình minh hoạ khi tính f(4):
deque-yeulaptrinh.pw
Để tìm l,r nhanh, ta dùng kĩ thuật sử dụng Deque tìm Min/Max trên đoạn tịnh tiến.

Code:

uses    math;
const   fi='';
        fo='';
        maxn=1000;
var     a:array[1..maxn,1..maxn] of byte;
        i,j,m,n,res,top:longint;
        h,s,left,right:array[1..maxn] of integer;
procedure nhap;
begin
    assign(input,fi);reset(input);
    readln(m,n);
    for i:=1 to m do
        for j:=1 to n do read(a[i,j]);
    close(input);
end;
procedure push(x:integer);
begin
    inc(top);
    s[top]:=x;
end;
function get:integer;
begin
    exit(s[top]);
end;
procedure pop;
begin
    dec(top);
end;
procedure xuly;
begin
    for i:=1 to m do
     begin
        for j:=1 to n do
           if a[i,j]=1 then
                begin
                    h[j]:=h[j]+1;
                end else h[j]:=0;
        top:=0;
        for j:=1 to n do
            begin
                while (top<>0) and (h[j]<=h[get]) do pop;
                if top=0 then left[j]:=0 else left[j]:=get;
                push(j);
            end;
        top:=0;
        for j:=n downto 1 do
                begin
                    while (top<>0) and (h[j]<=h[get]) do pop;
                    if top=0 then right[j]:=n+1 else right[j]:=get;
                    push(j);
                end;
        for j:=1 to n do
                begin
                    res:=max(res,h[j]*(right[j]-left[j]-1));
                end;
     end;
end;
procedure inkq;
begin
    assign(output,fo);rewrite(output);
    writeln(res);
    close(output);
end;
begin
    nhap;
    xuly;
    inkq;
end.

[Discrete Mathematics] Sets and Funtions

1. Sets

  • A set is an unordered collection of objects, called elements or members of the set.
  • A set is said to contain its elements
  • $ a \in A $ if a is element of A
  • $ a \notin A $ if a is not element of A
  • Ways to describe set
    • List all the members of a set (Roster method). E.g $ A = \{a, b, c, d\} $ (Roster method)
    • Use set builder notation: $ X = \{ x \mid P(x) \} $$$ E.g \ \ O=\{x \mid x \ is \ odd\} $$
  • A is a subset of B if and only if every element of A is also an element of B.$$ A \subseteq B \Leftrightarrow \forall x (x \in A \rightarrow x \in B) $$
  • Two sets are equal if and only if they have the same elements.$$ A = B \Leftrightarrow \forall x (x \in A \leftrightarrow x \in B) $$$$ A = B \Leftrightarrow A \subseteq B \land B \subseteq A $$
  • The empty set$\emptyset$$$ For \ every \ set \ \emptyset \subseteq S, S \subseteq S $$
  • Given a set $S$, the power set of $S$ is the set of all subsets of the set S. The power set of S is denoted by $\mathcal{P}(S)$

2. Set operations

  • The union of the sets A and B is the set that contains those elements that are either in A or in B, or in both.$$ A \cup B = \{x \mid x \in A \lor x \in B \} $$
  • The intersection of the sets A and B is the set containing those elements in both A and B.$$ A \cap B = \{x \mid x \in A \land x \in B \} $$
  • The difference of A and B is the set containing those elements that are in A but not in B. The difference of A and B is also called the complement of B with respect to A.$$ A \setminus B = \{ x \mid x \in A \land x \notin B \} $$

Table set identies

To be done

3. Cartesian product

  • The ordered n-tuple (a1, a2, . . . , an) is the ordered collection that has a1 as its first element, a2 as its second element, . . . , and an an as its nth element.
  • The Cartesian product of the sets A1, A2, . . . , An, denoted by A1 x A2 x · · · x An, is the set of ordered n-tuples (a1, a2, . . . , an), where ai belongs to Ai for i = 1, 2, . . . , n.$$A_1 × A_2 × · · · × A_n = \{ \ (a_1, a_2, . . . , a_n) \mid a_i ∈ A_i, i = 1, 2, . . . , n \ \} $$

4. Function

  • Let X and Y be nonempty sets. A function f from X to Y is an assignment of exactly one element of X to each element of Y$$ f : X \to Y $$
  • A function f is said to be one-to-one, or an injunction, if and only if f(a) = f (b) implies that a = b for all a and b in the domain of f (Injunctive)$$ \forall a \forall b (a \neq b \rightarrow f(a) \neq f(b)) $$
  • A function f from X to Y is called onto, or a surjection, if and only if for every element y ∈ Y there is an element x ∈ X with f(x) = y (Surjective)$$ \forall y \in Y, \exists x \in X : f(x) = y $$
  • A function f is a one-to-one correspondence, or a bijection, if it is both one-to-one and onto. (Bijective)$$ \forall y \in Y, \exists ! x \in X : f(x) = y $$
  • Let f be a function from the set X to the set Y and let g be a function from the set y to the set C. The composition of the functions g and f, is defined by is defined by (f ◦ g)(a) = f (g(a)).

5. Cardinality of Sets

Definition

The sets A and B have the same cardinality if and only if there is a one-to-one correspondence from A to B. When A and B have the same cardinality, we write |A| = |B|.

To be done

References

  • Discrete Mathematics and Its Applications 7th Edition, Kenneth H. Rosen
  • Đại số tuyến tính, Nguyễn Hữu Việt Hưng

[Discrete Mathematics] Logic and Proof

I. Logic and Proof

 

1. Propositional Logic

A proposition is a declarative sentence (that is, a sentence that declares a fact) that is either true or false, but not both.

Name Meaning Notation
negation not p $\lnot p$
disjunction p or q $p \lor q$
conjunction p and q $p \land q$
conditional if p, then q $p \rightarrow q$
biconditional p if and only if q $p \leftrightarrow q$

2. Propositional Equivalences

A compound proposition that is always true, no matter what the truth values of the propositional variables that occur in it, is called a tautology.

A compound proposition that is always false is called a contradiction.

A compound proposition that is neither a tautology nor a contradiction is called a contingency.

The compound propositions p and q are called logically equivalent if $p \leftrightarrow q $ is a tautology. ($p \equiv q$)

Equivalence Name
$$ p \lor F \equiv p $$

$$ p \land T \equiv p $$

Identity laws
$$ p \lor T \equiv T $$

$$ p \land F \equiv F $$

Domination laws
$$ p \lor p \equiv p $$

$$ p \land p \equiv p $$

Idempotent laws
$$ \lnot(\lnot p)) \equiv p $$ Double negation law
$$ p \lor q \equiv q \lor p $$

$$ p \land q \equiv q \land p $$

Commutative laws
$$ (p \lor q) \lor r \equiv p\lor(q\lor r) $$

$$ (p \land q) \land r \equiv p \land (q \land r) $$

Associative laws
$$ p \lor (q \land r) \equiv (p \lor q) \land (p \lor r) $$

$$ p \land (q \lor r) \equiv (p \land q) \lor (p \land r) $$

Distributive laws
$$ \lnot (p \land q) \equiv \lnot p \lor \lnot q $$

$$ \lnot (p \lor q) \equiv \lnot p \land \lnot q $$

De Morgan’s laws
$$ p \lor (p \land q) \equiv p $$

$$ p \land (p \lor q) \equiv p $$

Absorption laws
$$ p \lor \lnot p \equiv T $$

$$ p \land \lnot p \equiv F $$

Negation laws
Table of common Logical equivalence

3. Predicates and Quantifiers

To be done

References

Discrete Mathematics and Its Applications 7th Edition, Kenneth H. Rosen

Nhập, xuất dữ liệu trong C++

Trong bài này, chúng ta sẽ học cách nhập vào từ bàn phím (stdin standard input device) và ghi ra màn hình (stdout standard output device).

Ta cũng cần dùng đến thư viện iostream namespace std để hỗ trợ nhập xuất. Khi muốn dùng lệnh nào nằm trong namespace std, ta có 2 cách:

  • Khai báo using namespace std ở đầu chương trình, sau đó có thể dùng các lệnh này bình thường.
  • Thêm std:: vào trước lệnh ta muốn dùng. Ví dụ như std::cin, std::endl.

Từ đây trở đi, khi gặp std:: trước một lệnh, chúng ta sẽ tự hiểu lệnh sau đó nằm trong namespace std và có 2 cách như trên để viết.

std::cin

Để nhập dữ liệu cho biến, ta dùng lệnh cin

cin >> biến;

Nếu có nhiều biến cần nhập vào, ta có thể viết liên tiếp như sau

cin >> biến 1 >> biến 2 >> … >> biến n;

Khi chạy đến lệnh cin, chương trình sẽ chờ người dùng nhập dữ liệu vào các biến tương ứng. Dữ liệu nhập vào được phân cách nhau bởi dấu cách hoặc tab hoặc enter, và luôn được hiển thị ra màn hình.

Ví dụ

int a, b;
cin >> a >> b;

Lệnh cin ở dòng 2 sẽ yêu cầu người dùng nhập vào 2 giá trị tương ứng với 2 biến số nguyên a và b.

Lưu ý

Khi nhập vào, các giá trị được phân tách nhau bởi space (dấu cách), tab (dấu tab) hay enter (dấu xuống dòng). Nếu không, mặc dù trong một số trường hợp chương trình vẫn chạy nhưng rất khó kiểm soát được giá trị các biến nhập vào.
Ví dụ: đoạn mã sau

int a,b,c;  
cin>>a>>b>>c;  
hoặc
int a,b,c;
cin>>a; cin>>b; cin>>c;
khi thực hiện, ta nhập dữ liệu từ bàn phím: 3 4 5<enter> hoặc nhập:
3<enter>
4<enter>
5<enter>
Sau khi nhập xong biến a=3, b=4 và c=5.

std::cout

Để in dữ liệu ra màn hình, ta dùng lệnh cout

cout << biểu thức;

Ta cũng có thể in hàng loạt nhiều biểu thức liên tiếp nhau

cout << biểu thức 1 << biểu thức 2 << … << biểu thức n;

Biểu thức ở đây có thể hiểu là biểu thức toán học chứa biến, hằng, hay kết quả trả về của một hàm, …

Ví dụ

int a, b;
cin >> a >> b;
cout << a << ” + ” << b << ” = ” << a + b;

Lệnh cout ở dòng 3 in ra lần lượt: giá trị biến a, chuỗi ” + “, giá trị biến b, chuỗi ” = ” và giá trị biểu thức a + b.

Một số ký tự điều khiển

  • \a’ : tiếng chuông
  • \b’ : lùi lại một bước
  • \n’ : xuống dòng
  • \t’ : dấu tab
  • \\’ : dấu \
  • \?’ : dấu ?
  • \”‘ : dấu “

Lưu ý

std::endl cũng có chức năng tương tự ‘\n’ nhưng ngoài ra endl còn làm rỗng bộ đệm đầu ra.

Ví dụ

cout << ‘\t’ << “Hello World !\n” << 0;

Kết quả:

Hello World!
0

Lưu ý

cin dùng toán tử >> còn cout dùng toán tử <<. Đừng nhầm lẫn!

cout, cin nằm trong thư viện iostream

Định dạng in

Để dùng những lệnh định sau, ngoài thư viện iostream, ta còn phải dùng thư viện iomanip để định dạng. Các định dạng này cần được cout mới có tác dụng.

std::setw(n): quy định khoảng không gian cho dữ liệu được in ra màn hình là n. Nếu dữ liệu chiếm ít không gian hơn, dữ liệu sẽ được căn  lề phải khi in ra. Ngược lại , lệnh này không có ảnh hưởng, tức dữ liệu vẫn in ra như bình thường.

std::setprecision(n): quy định số chữ số được làm tròn khi in ra là n. Số chữ số được tính từ trái qua phải.

std::fixed: lệnh này đi kèm với setprecision sẽ xác định chỉ làm tròn các chữ số ở phần thập phân.

Ví dụ

cout << 12.345 << ‘ ‘;
cout << setprecision(2) << 12.345 << ‘ ‘;
cout << fixed << setprecision(2) << 12.345;

Kết quả:

12.345 12 12.35

Một số hàm khác liên quan đến nhập xuất

std::cin.get(c): nhập 1 ký tự vào biến c.

std::cin.getline(s, n): nhập tối đa n – 1 ký tự vào xâu s (ký tự thứ n là NULL).
std::getline (cin,str): đọc xâu kí tự str, str kiểu dữ liệu string.
std::cin.ignore(n): xóa n ký tự trong bộ đệm đầu vào.

fflush(stdin): xóa toàn bộ bộ đệm đầu vào.

Có thể bạn thích:
Nhập, xuất dữ liệu từ file trong C++

Bài tập mẫu

Viết chương trình nhập vào 3 số a, b, c. In ra trung bình cộng của 3 số đó với giá trị làm tròn đến chữ số thập phân thứ 5.

Code:

#include <iostream>
#include <iomanip>
 
using namespace std;
 
int main()
{
     cout << "Nhap 3 so a, b, c: ";
     float a, b, c;
     cin >> a >> b >> c;
     float avr = (a + b + c) / 3;
     cout << fixed << setprecision(5) << avr << endl;
     system("pause"); // Tạm dừng màn hình chờ nhấn Enter
     return 0;
}