PDA

Xem phiên bản đầy đủ : Số lần xuất hiện của ký tự trong xâu?


haihang_84
18-02-2008, 08:53
Các thầy cô giúp em giải bài tập 2 - bài thực hành 5 - tin học 11 nhé. Bài này như sau:
Viết chương trình nhập từ bàn phím một xâu kí tự S và thông báo ra màn hình số lần xuất hiện của mỗi chữ cái tiếng Anh trong S (không phân biệt chữ hoa hay chữ thường).
Mong các thầy cô sớm hồi âm.

admin
18-02-2008, 10:02
Var a: array['A'..'Z'] of Integer;
s: String;
i: Integer;
c: Char;
Begin
For c:= 'A' to 'Z' do
a[c]:= 0;

Write('Nhap chuoi S: ');
Readln(s);

For i:=1 to Length(s) do
Begin
c:= Upcase(s[i]);
if ('A' <= c) and (c <= 'Z') then
Inc(a[c]);
End;

For c:='A' to 'Z' do
If a[c] > 0 then
Writeln('Ky tu ',c,' xuat hien ',a[c],' lan.');
End.

haihang_84
18-02-2008, 20:43
Em cảm ơn thầy Admin nhiều lắm. Bài này em làm mãi chẳng được.Hihi.

admin
18-02-2008, 21:38
Cách này có nhược điểm là dùng nhiều bộ nhớ (vì chứa luôn số lần xuất hiện của các ký tự không có trong chuỗi s).

Nhưng đạt tốc độ cao vì dùng ký tự làm chỉ mục cho mảng nên không cần phải tìm.

hungpro
20-02-2008, 16:07
Admin đúng là admin. Khâm phục, khâm phục...

dancamxuyen
20-02-2008, 17:01
var st: string;
i,d:byte;
ch:char;
Begin
write('nhap vao mot xau bat ki'); Readln(st);
for ch:='A' to 'Z' do
begin
d:=0;
for j:= 1 to lenght(st) do
if ch=upcase(st[i]) then d:= d+1;
write(' so ki tu ', ch ,' co trong xau la', d);
end;
readln;
end.
{================================================= =}
:confused: Các bạn xem và cho ý kiến nhé.

dancamxuyen
20-02-2008, 17:04
Với cách này ta không cần một biến mảng chứa số các kí tự có trong xâu. Nhưng mà vẫn in ra thông báo là không có kí tự nếu kí tự đó không xuất hiện trong xâu.:confused:

admin
20-02-2008, 17:08
for ch:='A' to 'Z' do
begin
d:=0;
for j:= 1 to lenght(st) do
if ch=upcase(st[i]) then d:= d+1;
write(' so ki tu ', ch ,' co trong xau la', d);
end;
Cách của bạn hoàn toàn đúng.

Bạn đã chọn giải pháp ít tốn bộ nhớ (không dùng mảng) nhưng bù lại bạn tăng số phép tính thông qua 2 vòng lặp lồng nhau là 26*length(st).

dancamxuyen
20-02-2008, 17:16
Mỗi cách thì có một ưu điểm nhưng theo tôi thì cách này làm học sinh hiểu nhiều hơn về lệnh For.. to do.... lồng nhau. và hiểu rõ hơn vê lệnh GHÉP

TONI
06-03-2008, 09:38
Mình giải bài tập số 2 trang 73 sách giáo khoa lớp 11(BTTH số 5) thế này:
Các bạn xem thử và góp ý nhé.
-Ý tưởng của mình trong bài này là rèn luyện các kiến thức về mảng và xâu của chương 4 có kết hợp sử dụng các cấu trúc điều khiển đã học trước đó.
-Trong trường hợp chỉ đếm và in ra màn hình mà không lưu trong bộ nhớ( ở đây là mảng) thì bài làm đơn giản hơn.
-Đây chỉ là một cách làm, mong các bạn nhận xét và cho cách khác hay hơn với lưu ý đến mục tiêu của bài TH so 5

TONI
06-03-2008, 09:41
bai tap day

admin
06-03-2008, 09:49
E:\dulieu\bt2.doc (E:%5Cdulieu%5Cbt2.doc)Link này không hợp lệ bạn ơi! Bạn phải upload lên diễn đàn thông qua chức năng "Quản lý các đính kèm" khi đăng bài ở Chế độ đầy đủ.

TONI
06-03-2008, 09:51
Em đang làm đây, cảm ơn ADM

tungld
06-03-2008, 09:52
bạn up bài giải của bài này lên diễn đàn đi. ý tưởg của bạn chưa rõ ràng lắm, theo mình hiểu bạn duyệt sâu nhiều lần, mỗi lần đếm một ký tự đúng không? như vậy mất rất nhiều thời gian, bài này sử dụng thuật toán "Lùa bò vào chuồng" là hợp lý nhất.

TONI
06-03-2008, 09:58
Cảm ơn bạn đã góp ý, mình đã post lên rồi đấy, không phải duyệt nhiều lần mà là một lần duyệt thôi, nhưng mỗi lần duyệt phải so sánh từ a tới ..z.
Bạn có bài hay post lên nhé.

tungld
06-03-2008, 10:07
Mình đã đọc bài của bạn. ý tưởng của bạn chính là lùa bò vào chuồng đó. cách này rất tốt và rất dễ hiểu. tuy nhiên khi giảng cho Hs cần nói thêm các phần tử của mảng có thể là ký tự. mình đã cho HS làm bài này rùi . OK.

TONI
06-03-2008, 10:38
Cảm ơn tungld

quyenlh
06-03-2008, 20:02
Làm phiền thầy giải thích giúp tôi tại sao lại gọi là thuật toán "Lùa bò vào chuồng" . ???
Tôi mới nghe lần đầu nên thắc mắc mãi!

tungld
06-03-2008, 20:11
Làm phiền thầy giải thích giúp tôi tại sao lại gọi là ???
Tôi mới nghe lần đầu nên thắc mắc mãi!
Em xin giải thích bằng cách kể một câu chuyện thế này nhé.
Có một đàn bò đang gặm cỏ trên đồng, để đếm được mỗi loại bò có bao nhiêu con, nếu như đếm luôn trên cánh đồng đó thì mất rất nhiều thời gian và có thể bỏ sót. để thực hiện điều đó, người ta lùa tất cả số bò đó vào chuồng sao cho mỗi loại bò lùa vào một chuồng riêng. Ví dụ bò trắng có chuồng riêng, bò vàng có chuồng riêng. sau đó người ta chỉ cần đếm số bò trong chuồng là biết được mỗi loại có bao nhiêu con. tương tự để giải bài toán trên, ta coi mỗi ký tự là một loại bò, cần tạo mảng để lưu tần suất xuất hiện các ký tự (tương ứng là chuồng của bò). dùng vòng lặp đề "lùa" các ký tự vào "chuồng" của nó. sau đó đếm lại số lần xuất hiện các ký tự trong mảng thôi. đây là câu chuyện mà em đã được nghe từ khi còn đang học, nay kể lại thì đại ý là vậy.

Tu Quang
07-03-2008, 08:18
Bài toán này bạn phải xử lý các trường hợp chữ hoa và chữ thường:
- Chuyển tất cả về hoa
- Hay chuyển tất cả về thường
- Hay là nhận biết cả hai (nên dùng cách này)

TONI
07-03-2008, 08:30
Thầy ơi!Hôm qua chưa kịp hỏi thì có bạn đã hỏi rồi.
Cảm ơn thầy chia sẻ cái tên nghe là lạ này, theo mình nuôi bao nhiêu bò mà làm nhiều chuồng thế?
Vui vậy thôi, cái tên đó dễ nhớ TT hơn nhỉ.

TONI
07-03-2008, 08:34
Bài toán này bạn phải xử lý các trường hợp chữ hoa và chữ thường:
- Chuyển tất cả về hoa
- Hay chuyển tất cả về thường
- Hay là nhận biết cả hai (nên dùng cách này)
Cảm ơn bạn đã trao đổi
Mình đã nói rõ là bài tập 2 ,bài thực hành số 5 SGK Tin lớp 11.(không phân biệt chữ hoa hay thường, mình chỉ đếm chữ thường thôi),còn đầy đủ là:
type mang_dem_SL_kitu=array ['a'..'z'] of integer;
var xauS: string;
m:mang_dem_SL_kitu;
i:integer;
j:char;
begin
write('nhap xau: ');readln(xauS); {nhap xau}
for i:=1 to length(xauS) do {duyet va dem chu cai tieng Anh}
for j:='a' to 'z' do if (xauS[i]=j or(xauS[i]=upcase(j))
then m[j]:=m[j]+1;
for j:='a' to 'z' do {in ket qua ra man hinh}
if m[j]>0 then
begin
write('so ki tu ',j,' trong xau la:',m[j]);
writeln;
end;
readln;
end.

tungld
07-03-2008, 08:47
Theo mình chương trình của bạn sử dụng hai câu lệnh For .. do lồng nhau thì chưa tối ưu. Theo mình nên cài đặt chương trình như sau sẽ đếm được kí tự in hoa và giảm bớt phép toán.
program BTTH5_Bai2;
type mang_dem_xau_ki_tu =array['A'..'Z'] of byte;
var s:string; m:mang_dem_xau_ki_tu;
i:byte; j:char;
begin write('Nhap xau:');
readln(s);
{xu ly ky tu viet hoa}
for i:=1 to length(s) do s[i]:=upcase(s[i]);
{duyet dem chu cai trong xau}
for i:=1 to length(s) do if (s[i]>='A') and (s[i]<='Z') then inc(m[s[i]]);
For j:= 'A' to 'Z' do
writeln('ky tu ', j, ' xuat hien ', m[j], 'lan');
readln;
end.

tungld
07-03-2008, 08:54
Ch­ương trình như sau các thầy xem thử:
program BTTH5_Bai2;
type mang_dem_xau_ki_tu =array['a'..'z'] of byte;
var s:string;
m:mang_dem_xau_ki_tu;
i:byte;
j:char;
begin
write('Nhap xau:'); readln(s);
{duyet dem chu cai trong xau}
for i:=1 to length(s) do
if (s[i]>='a') and (s[i] <='z') then inc(m[s[i]]);
{in ket qua ra man hinh}
for j:='ato 'z' do
if m[j]<>0 then writeln('so ki tu ', j, ' trong xau la: ',m[j]);
readln;
end.

TONI
07-03-2008, 09:12
begin
write('Nhap xau:'); readln(s);
{duyet dem chu cai trong xau}
for i:=1 to length(s) do
if (s[i]>='a') and (s[i] <='z') then inc(m[s[i]]);
Thầy tungls ơi, đoạn này chỉ đếm chữ cái thường còn khi gặp chữ cái in hoa là không đếm được rồi, mà như thế không đúng với yêu cầu của bài tập 2

TONI
07-03-2008, 09:15
begin
write('Nhap xau:'); readln(s);
{duyet dem chu cai trong xau}
for i:=1 to length(s) do
if (s[i]>='a') and (s[i] <='z') then inc(m[s[i]]);
Đoạn này chỉ đếm chữ thường thôi phải không thầy?

tungld
07-03-2008, 09:21
Nếu muốn đếm chữ hoa nữa thì mình chỉ cần tạo lại xâu S với nội dung là các chữ hoa rồi xử lý là được mà:
For i:= 1 to length(s) do S[i]:=upcase(s[i]);
sau đó sửa các ký tự 'a' thành 'A' và 'z' thành 'Z' là được mà.
chương trình được viết lại:
program BTTH5_Bai2;
type mang_dem_xau_ki_tu =array['A'..'Z'] of byte;
var s:string;
m:mang_dem_xau_ki_tu;
i:byte;
j:char;
begin
write('Nhap xau:'); readln(s);
{Viet hoa xau S}
for i:=1 to length(s) do s[i]:=upcase(s[i])
{duyet dem chu cai trong xau}
for i:=1 to length(s) do
if (s[i]>='A') and (s[i] <='Z') then inc(m[s[i]]);
{in ket qua ra man hinh}
for j:='A’ to 'Z' do
if m[j]<>0 then writeln('so ki tu ', j, ' trong xau la: ',m[j]);
readln;
end.

TONI
07-03-2008, 09:47
Thanks Tungld!
Theo mình nghĩ bài này mình phải căn cứ theo yêu cầu BT2. Ở đây bài tập nói không phận biệt chữ hoa và chữ thường, tức là:
Input: Xâu có thể lẫn lộn chữ hoa và chữ thường.
Output:Số chữ cái(VD: AaaBbbB thì KQ:chữ a:3, chữ b 4)
Bài của thầy hoặc là chỉ đếm được chữ hoa (bỏ qua chữ thường)
for i:=1 to length(s) do
if (s[i]>='A') and (s[i] <='Z') then inc(m[s[i]]);
hoặc là chỉ đếm được chữ thường (bỏ qua chữ hoa):
for i:=1 to length(s) do
if (s[i]>='a') and (s[i] <='z') then inc(m[s[i]]);
Theo mình nếu theo yêu cầu bài tập(như vD trên), không phân biệt thì ta dùng:
for i:=1 to length(xauS) do {duyet va dem chu cai tieng Anh}
for j:='a' to 'z' do if (xauS[i]=j or(xauS[i]=upcase(j))
then m[j]:=m[j]+1;
Còn nếu phân biệt thì ta phải dùng thêm một biến mảng nữa.
Chào thầy tungld.

tungld
07-03-2008, 09:50
Chương trình của mình đã test và cho kết quả đúng.
câu lệnh For i:=1 to length(s) do s[i]:=upcase(s[i]) cho phép viết hoa tất cả các chữ cái.
ví dụ: S ='AaaBbbB' thì S='AAABBBB'
vậy là có 3 chữ A và 4 chữ B.
Thân.

TONI
07-03-2008, 09:59
Hì hì
Thầy cũng kiên trì đấy nhỉ, bây giờ thì mình hiểu ý thầy tungld rồi. Bài giải của thầy là đúng với bài tập 2.(Ý thầy là nhập xâu vào, sau đó ta đổi thành toàn chữ hoa(lúc này đếm chữ hoa) hoặc đổi thành toàn chữ thường(đếm chữ thường).OK)
Mình tưởng thầy mở rộng bài này ra(phân biệt A và a).Khổ quá!
Chúc thầy sức khoẻ.

TruongVu
07-03-2008, 10:33
[QUOTE=dancamxuyen;18820]var st: string;
i,d:byte;
ch:char;
Begin
write('nhap vao mot xau bat ki'); Readln(st);
for ch:='A' to 'Z' do
begin
d:=0;
for j:= 1 to lenght(st) do
if ch=upcase(st[i]) then d:= d+1;
write(' so ki tu ', ch ,' co trong xau la', d);
end;
readln;
end.
{================================================= =}

Hình như là chương trình có một vài lỗi đó bạn ơi, không giống như yêu cầu bài toán, in ra tất cả số lần xuất hiện của bảng chữ cái luôn ... :(

tungld
07-03-2008, 11:00
Hì hì
Thầy cũng kiên trì đấy nhỉ, bây giờ thì mình hiểu ý thầy tungld rồi. Bài giải của thầy là đúng với bài tập 2.(Ý thầy là nhập xâu vào, sau đó ta đổi thành toàn chữ hoa(lúc này đếm chữ hoa) hoặc đổi thành toàn chữ thường(đếm chữ thường).OK)
Mình tưởng thầy mở rộng bài này ra(phân biệt A và a).Khổ quá!
Chúc thầy sức khoẻ.


Khi học sinh thực hành xong bài này. mình có thể đưa bài tập mở rộng bằng cách phân biệt chữ hoa và chữ thường được mà. ví dụ: AaaBbbb thì được kết quả là:
ký tự a xuất hiện: 2
ký tự b xuất hiện : 3
ký tự A xuất hiện: 1
ký tự B xuất hiện 1
Như vậy HS sẽ phải suy nghĩ nhiều hơn. nếu tiết thực hành chưa giải quyết được thì yêu cầu học sinh về nhà làm và nộp lại bài.
Thân.

TONI
07-03-2008, 14:02
Cảm ơn thầy đã chia sẻ!
Hướng giải quyết vấn đề của thầy rất hợp lý.

TONI
07-03-2008, 14:04
Chứ lâu nay bạn ít lên DD đúng không, cách đây mấy ngày mình có post bài lên rồi đấy.
Mong bạn tải về được.
Thân chào

hoatrangnguyen2008
09-08-2008, 07:48
Đây là bài 4.39 trong Sách BT tin học lớp 11 trang 45.

Nhập vào một xâu S, gồm các ký tự La tinh in thường và các ký tự số từ 0 đến 9 . Đếm và đưa ra màn hình số ký tự khác nhau trong xâu S.

Rất mong các thầy giúp dỡ. Em cảm ơn

tranhaothien
22-09-2008, 23:38
:) thấy mấy Thầy hăng hái, tui cũng tham gia một bài, mong mấy thầy cho ý kiến nghen!

Program Dem_ki_tu;
Uses crt;
Var
S: string;
bA: array['A'..'Z']of byte;
i: char;
j: byte;
Begin
clrscr;
writeln('Nhap vao chuoi ki tu: ');
readln(S);
{khoi tao gia tri ban dau cho mang bA}
for i:= 'A' to 'Z' do
bA[i]:=0;
{Dem cac ki tu trong chuoi S}
for j:=1 to length(S) do
begin
S[j]:= upcase(S[j]);
bA[S[j]]:= bA[S[j]] + 1;
end;
{Xuat ket qua}
for i:='A' to 'Z' do
if(bA[i]>0 ) then
write(i:3, ' co ',bA[i], ' ki tu',' ; ' );

Readln;
End.

hatrunghoa
25-09-2008, 08:26
Đây là bài 4.39 trong Sách BT tin học lớp 11 trang 45.

Nhập vào một xâu S, gồm các ký tự La tinh in thường và các ký tự số từ 0 đến 9 . Đếm và đưa ra màn hình số ký tự khác nhau trong xâu S.

Rất mong các thầy giúp dỡ. Em cảm ơn
Đơn giản là bạn sắp xếp lại xâu rồi đếm

tranthu
17-11-2008, 09:55
Pascal học nhiều rồi mà bây giờ tôi chẳng biết dạy Pascal cho học sinh để làm gì. Ngày xưa tôi học có máy tính về nhà thực hành đều đều mà còn nhiều chỗ không hiểu mà bây giờ bắt học sinh của ta học toàn bộ chương trình trong khi đó chỉ có 2 tiết/ tuần thì làm sao mà học sinh học được?
Với lại tui thấy Pascal không nên đưa vào chương trình học, chương trình lập trình cơ bản nhất nên đưa vào học là C, thiết thực và gần với những ứng dụng sau này hơn.
Còn về bài này, tôi đồng ý với cách làm thứ 2 hơn, vì học sinh sẽ dễ hiểu hơn cách đặt biến d thay vì mảng a như bác admin làm.

Fong
18-11-2008, 03:28
Pascal học nhiều rồi mà bây giờ tôi chẳng biết dạy Pascal cho học sinh để làm gì.
Bạn có phải là giáo viên dạy Tin không vậy?

Kujuna
22-02-2011, 22:59
Var a: array['A'..'Z'] of Integer;
s: String;
i: Integer;
c: Char;
Begin
For c:= 'A' to 'Z' do
a[c]:= 0;

Write('Nhap chuoi S: ');
Readln(s);

For i:=1 to Length(s) do
Begin
c:= Upcase(s[i]);
if ('A' <= c) and (c <= 'Z') then
Inc(a[c]);
End;

For c:='A' to 'Z' do
If a[c] > 0 then
Writeln('Ky tu ',c,' xuat hien ',a[c],' lan.');
End.

Anh Admin viết thiếu "readln" sau "End."

Kujuna
22-02-2011, 23:06
var st: string;
i,d:byte;
ch:char;
Begin
write('nhap vao mot xau bat ki'); Readln(st);
for ch:='A' to 'Z' do
begin
d:=0;
for j:= 1 to lenght(st) do
if ch=upcase(st[i]) then d:= d+1;
write(' so ki tu ', ch ,' co trong xau la', d);
end;
readln;
end.
{================================================= =}
:confused: Các bạn xem và cho ý kiến nhé.

Bạn đã test chưa thế? Output sai rồi. Mà "j:=1 to" là sao? Phải là "i:=1 to" chứ.

dzt
08-10-2011, 12:05
Vấn đề đã được bác admin giải đáp rất tốt và đó là cách mà tôi dùng để giải bài này cho học sinh.

Để có tốc độ đôi khi ta phải chấp nhận tiêu tốn nhiều bộ nhớ và ngược lại, để tiết kiệm bộ nhớ, ta cần phải hy sinh tốc độ.

Vấn đề chính là bài giải rõ ràng để học sinh có thể tiếp thu. Còn cải tiến gì gì đó thì tôi không cần thực hiện vì đối tượng tôi dạy chỉ cần hiều được vấn đề và có thể tự mình suy luận các hướng mở rộng. Cải tiến có thể để lên bậc đại học hoặc cho các khối chuyên Tin.