Cần giải thích đoạn code vận dụng mã ASCII

Mọi người giải thích giúp em chỗ ngay=ngay*10+s[i]-48; cô bảo bận vận dụng mã ascill trong string

bool check(string s)
{
	int nam=0,thang=0,ngay=0,i=0;
	while(s[i]!='/')
	{
		ngay=ngay*10+s[i]-48;
		i++;
	}
	i++;
	while(s[i]!='/')
	{
		thang=thang*10+s[i]-48;
		i++;
	}
	i++;
	while(i<s.size())
	{
		nam=nam*10+s[i]-48;
		i++;
	}
	if(nam>1996)
	    return true;
	if(nam==1996&&thang>10)
	    return true;
	if(nam==1996&&thang==10&&ngay>10)
	    return true;
	return false;
}

nhìn vào biểu thức có thể thấy, tất cả chỉ là phép cộng trừ nhân, không có gì hơn
vấn đề là s[i], vì s là string, nên s[i] nó là kí tự char
nhìn kĩ hơn thì các kí tự s[i] này sẽ là số (nếu như chuỗi đúng format mong đợi)
vậy bạn hãy thử lấy một kí tự số trừ cho 48 xem nó ra kết quả là gì?

int ngay = 2;
ngay = ngay * 10 + '3' - 48;

hãy thử chạy và reply lại topic này

7 Likes

nhưng có một điểu em chưa hiểu là tại sao lấy s[i]-48, mà không phải lấy ngày nhân 10 thôi, s[i]-48 thì giá trị nó bằng không thì có nhất thiết phải đưa vào ko, em xóa đi thì chương trình không chạy =((

em thêm như anh nói thì chương trình vẫn chạy, nhưng em vẫn ko hiểu bản chất của việc trừ đi 48.

Bạn thấy lúc nào đó cũng bằng 0?
Bạn đã thử chạy 2 dòng code của mình ví dụ chưa?
Sau đó bạn đã thử thay đổi ‘3’ thành ‘4’ hay số nào đó chưa?
Bạn thấy kết quả gì?

4 Likes

em thay đổi như lời anh nói thì khi nhập danh sách vẫn bình thường nhưng khi thực hiện yêu cầu thứ 5 là xóa những người sinh sau ngày 10/10/1996 thì nó xóa toàn bộ danh sách ạ
đây là code ban đầu của e ạ: http://codepad.org/wXw5nMgO

và việc khai báo biến i = 0 ở đây có tác dụng j vậy ạ.

bạn đang hỏi việc sử dụng phép công cho kí tự ascii
mình gửi bạn 2 dòng code, và muốn bạn chạy 2 dòng code mình đã gửi, chỉ 2 dòng code của mình (bằng cách thêm include, khai báo, main và in) và xem kết quả, rồi sau đó bạn không hiểu gì về 2 dòng code đó thì hỏi tiếp

5 Likes

Ngày tháng của cậu là chữ cái (ví dụ: ‘3’), cậu cần convert nó sang số 3 để có thể tính toán.
Để cậu convert chữ cái ‘3’ ra số 3, cậu chỉ cần tính khoảng cách của chữ cái ‘3’ với chữ cái ‘0’.
Mã ASCII của chữ cái ‘0’ là 48.

Về biến i, đó là biến để cậu duyệt lần lượt các chữ cái của xâu.

Cậu nên kiên nhẫn làm theo hướng dẫn của @kisuluoibieng, thử chạy code của cậu với một số đầu vào nhất định, giải thích từng dòng môt, cậu sẽ hiểu thôi.

Hope it helps!

4 Likes

dạ vâng, em đã thử viết một chương trình như anh nói rồi ạ, và khi e thay đổi giá trị trongngay = ngay * 10 + ‘3’ - 48; thành 4 thành 5 thì được kết quả là 23, 24, 25.ở đây em có thể hiểu là để chuyển đổi cái kí tự 3 4 5 mà ta nhập vào sag số để tính toán thì ta phải tính khoảng cách của kí tự số 3 4 5 với kí tự 0
Mã ascii của kí tự không là 48 , em thắc mắc là vậy 3 4 5 ở biểu thức này để làm gì cuxg như a[i] ở đây để làm gì tại sao thiếu chúng và chỉ để ngay= ngay*10 chương trình lại sai ạ. em xin cảm ơn.

cảm ơn những chia sẻ của anh nhiều ạ <3, em sẽ rút kinh nghiệm lần sau.

2 Likes

Nếu cậu nhập “23/12/2022”, cậu có thể giải thích chi tiết từng bước khi đoạn code này được chạy không?

    while(s[i]!='/')
	{
		ngay=ngay*10+s[i]-48;
		i++;
	}
5 Likes

để cho chương trình nó đúng
còn như thế nào là đúng khi để nó và như thế nào lại sai thì phải phải tự biết chứ nhỉ
ở đây chỉ hỗ trợ để bạn có thể hiểu các vấn đề liên quan đến cú pháp hoặc ngữ nghĩa của hàm/lệnh
còn ngữ nghĩa của chương trình thì bạn tự tìm hiểu hoặc đi học tác giả chứ

int a = 1;
int b = 1;
int c = a + b;  // tại sao chỗ này c = a + b, sao không bỏ b? công b để làm gì?
cout<<c; 
5 Likes

Theo cách hiểu của e, thì điều kiện trong while để khi nhập xâu vào ví dụ như nhập “23/12/2022” thì sẽ loại bỏ các kí tự " / " và duyệt xâu, ngày*10 để cộng dồn vào thành số, ví dụ lần cộng đầu nó đc 2
thì lần sau nhân 10 để chuyển 2 thành hàng chục còn vế sau thì em chưa thông ạ.

vâng a, em cảm ơn anh nhiều <3

Hi there,
Vế nào cậu chưa thông vậy? :smile:
Cậu hiểu ý tưởng cơ bản của đoạn code đó rồi. Thực ra, tớ muốn cậu giải thích từng bước một, kiểu:

  • Với i = 0, s[0] = ‘2’ (không phải ký tự ‘/’), tính ngày = 0 * 10 + ‘2’ - 48 = 2.
    Rồi tăng i lên 1.
  • Với i = 1, s[1] = ‘3’ (không phải ký tự ‘/’), tính ngày = 2 * 10 + ‘3’ - 48 = 20 + 3 = 23.
    Rồi tăng i lên 1.
  • Với i = 2, s[2] = ‘/’, thoát vòng lặp.

Như vậy, ngày của cậu được tính ra là 23, từ xâu “23”.
Nếu cậu giải thích được phần còn lại của code theo kiểu từng bước như vậy, cậu sẽ hiểu đoạn code, mà không phải hỏi câu thế này:

em thắc mắc là vậy 3 4 5 ở biểu thức này để làm gì cuxg như a[i] ở đây để làm gì tại sao thiếu chúng và chỉ để ngay= ngay*10 chương trình lại sai ạ.

3 Likes

ui, em hiểu rồi ạ. Cảm ơn anh nhiều haha.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?