[Powered by Google Translate] Mục Vấn đề Set 2: Edition Hacker
Rob Bowden, Đại học Harvard
Đây là CS50. CS50.TV
Vì vậy, tôi là Rob. Tôi là một cấp cao trong Kirkland. Đây là năm thứ ba của tôi TFing CS50.
Đây là lần đầu tiên mà chúng tôi đang thay đổi từ phần bài giảng theo phong cách truyền thống,
nơi mà chúng tôi chỉ xem xét những gì đã xảy ra trong bài giảng và sau đó bạn đặt câu hỏi,
ngay bây giờ để được rất nhiều dựa trên vấn đề, chúng tôi sử dụng không gian, và -
Oh, do đó, ý tưởng là để đi đến liên kết tôi đã gửi cho bạn và sau đó bạn sẽ có trong không gian của tôi.
Có ai không có một máy tính xách tay? Okay.
Vì vậy, chúng ta sẽ được sử dụng điều này, và chúng ta sẽ được thực hiện vấn đề sống trong phần
và thảo luận và tìm ra những gì sai
và tôi có thể kéo lên một số mã của bạn, và tôi có thể thảo luận về các ý tưởng của bạn.
Vì vậy, có ai gặp khó khăn?
Bạn có thể trò chuyện ở bên cạnh, tôi không biết nếu chúng ta sẽ có lý do cho điều đó.
Bây giờ, như supersection trước, nếu bạn đang ở lớp đó, bạn biết đó là về.
Trên tất cả các bộ P có được những phần này.
Vì vậy, P-set 2, chi tiết kỹ thuật, tôi đoán bạn nhìn thấy nó trên P-set 1 đã.
Nhưng chúng ta có thể nhìn vào P-set 2 cho những gì chúng ta sẽ đi qua ngày hôm nay.
Và bạn sẽ thấy một phần của câu hỏi.
Vì vậy, đây sẽ là trong tất cả các P-bộ, sẽ có một phần của câu hỏi.
Vì vậy, đến nay chúng tôi đã nói, "Hãy xem xét điều này một cơ hội để thực hành."
Bạn sẽ không được yêu cầu nộp chương trình này.
Ý tưởng là những có nghĩa vụ phải loại giúp bạn bắt đầu với bộ vấn đề.
Tôi đoán trên phiên bản Hacker, rất nhiều trong số họ có nghĩa vụ phải chỉ là mới, những điều thú vị để tìm hiểu.
Họ có thể không được trực tiếp áp dụng đối với các thiết lập vấn đề.
Và ngay bây giờ chúng ta không có bạn gửi cho họ, nhưng trong lý thuyết,
cho bộ vấn đề sau, bạn có thể trình, và do đó bạn có thể đến phần
hoặc xem các phần để có được câu trả lời, hoặc bạn chỉ có thể nhận được chúng trên của riêng bạn
nếu bạn không cảm thấy như thưởng thức sự hiện diện của tôi.
Vì vậy, tôi nghĩ rằng đây là một trong những người đầu tiên.
Oh. Ngoài ra, theo các phần câu hỏi, chúng tôi cũng đã đặt câu hỏi về quần short.
Vì vậy, tôi đoán, trong lý thuyết, bạn đang nghĩ xem những trước khi đến phần,
nhưng đó là tiền phạt nếu bạn không, chúng ta sẽ đi qua chúng anyway.
Vì vậy, chúng ta có thể bắt đầu với những: "Làm thế nào để một vòng lặp trong khi khác nhau từ một vòng lặp do-trong khi?
Khi là sau này đặc biệt hữu ích? "
Vì vậy, bất cứ ai có bất kỳ?
[Sinh viên] do-trong khi vòng lặp sẽ luôn luôn thực hiện ít nhất một lần.
Vâng. Vì vậy, đó là sự khác biệt. Một trong khi vòng lặp - sẽ chỉ làm điều đó ở đây - trong khi vòng lặp, chúng ta có điều kiện
ngay tại đây, trong khi một do-trong khi, bạn không có điều kiện cho đến khi chúng tôi xuống đây.
Và như vậy, khi chương trình của bạn đang thực hiện, và nó được đến vòng lặp trong khi,
nó ngay lập tức kiểm tra nếu tình trạng này là đúng sự thật.
Nếu tình trạng đó là không đúng, nó sẽ chỉ bỏ qua các vòng lặp hoàn toàn.
Do-trong khi vòng lặp, như các chương trình được thực hiện, nó được cho là "làm".
Không có gì xảy ra vào thời điểm này, chỉ cần tiếp tục thực hiện.
Sau đó, khi nó cập "trong khi," nếu điều kiện là đúng, vòng lặp sẽ trở lại và làm điều đó một lần nữa
và một lần nữa và một lần nữa cho đến khi điều kiện là không đúng sự thật và sau đó chỉ cần rơi xuống.
Vì vậy, sự khác biệt là, rằng điều này có thể bỏ qua ngay từ khi bắt đầu.
Điều này nhất thiết phải thực hiện một lần và sau đó có thể thực hiện nhiều lần hơn nếu tình trạng này vẫn là sự thật.
Vì vậy, vòng lặp while sẽ chỉ làm điều đó một lần, hoặc vòng lặp trong khi chúng ta có thể không cần phải làm điều đó cả,
kể từ ngay khi chúng tôi nhận được để nó, nếu điều kiện là sai, chúng tôi sẽ chỉ nhảy qua nó.
Trong khi đó, làm trong khi vòng lặp, chúng tôi sẽ thực hiện nó một lần, nhất thiết phải.
Sau đó, khi chúng tôi nhận được tình trạng này, chúng tôi kiểm tra nếu nó là đúng hay sai.
Nếu đó là sự thật, chúng tôi sẽ làm điều đó một lần nữa, nếu nó sai, chúng ta sẽ tiếp tục.
Vì vậy, khi sau này đặc biệt hữu ích?
Vì vậy, tôi có thể nói rằng trong toàn bộ 4 năm, 3 năm, bất cứ điều gì,
mà tôi đã được lập trình, tôi đã sử dụng điều này, như thế, dưới 10 lần.
Và có lẽ 5 người họ trong CS50 khi chúng tôi giới thiệu làm trong khi các vòng.
Vì vậy, khi bạn đã sử dụng làm trong khi các vòng?
Khi nào là yeah?
[Sinh viên] Khi bạn đang cố gắng để có được đầu vào của người dùng, hoặc một cái gì đó bạn muốn kiểm tra -
Yeah. Vì vậy, trong khi các vòng, người sử dụng đầu vào là lớn.
Đó là lý do tại sao các bộ vấn đề đầu tiên, khi bạn muốn yêu cầu người dùng, như,
"Cho tôi một chuỗi," bạn không thể tiếp tục cho đến khi bạn nhận được rằng chuỗi.
Và như vậy bạn nhất thiết, cần phải hỏi cho chuỗi ít nhất một lần.
Nhưng sau đó nếu họ trả lời cái gì xấu, sau đó bạn cần phải lặp lại và hỏi lại lần nữa.
Nhưng khác với người dùng nhập vào, nó rất hiếm hoi mà tôi gặp phải một trường hợp
nơi mà tôi muốn để lặp "ít nhất một lần", nhưng có thể nhiều hơn.
Câu hỏi hay - Có ai sử dụng một do-trong khi vòng lặp bất cứ nơi nào khác?
Okay. Vì vậy, một trong những tiếp theo là, "Cái gì không không khai báo định danh
thường chỉ ra nếu kết quả bằng cách kêu vang? "
Vì vậy, tôi có thể viết loại mã để có được 'định danh không khai báo?
[Sinh viên] Đó là x = 2?
Vì vậy, chúng tôi chỉ có thể thử nó ở đây, x = 2.
Chúng tôi sẽ chạy này - oh, tôi không nhấp vào nó. Vì vậy, ở đây chúng tôi nhận được - tất cả các quyền.
"Sử dụng định danh không khai báo x".
Vì vậy, đó là định danh không khai báo, một biến.
Nó thường xuyên sẽ gọi một định danh một biến.
Vì vậy, nó có thể không biết nó thực sự là một biến, nó không biết nó là gì.
Vì vậy, nó là một định danh.
Vậy tại sao nó không khai báo? Yeah.
Vì vậy, để được rõ ràng về thuật ngữ, việc kê khai của một biến
là khi bạn nói "x int," hoặc "chuỗi y", bất cứ điều gì.
Việc khởi tạo của biến, hoặc phân công của biến,
là bất cứ khi nào bạn nói "x = 2."
Vì vậy, chúng ta có thể làm điều này trong bước riêng biệt, int x, x = 2, và cho đến khi chúng tôi có thể có một loạt các công cụ ở đây -
nhưng cho đến khi dòng này xảy ra, x vẫn chưa được khởi tạo, nhưng nó đã được tuyên bố.
Và vì vậy chúng tôi rõ ràng có thể làm điều đó trong 1 dòng, và bây giờ chúng tôi đang kê khai, khởi tạo.
Câu hỏi?
Và cuối cùng, "Tại sao là yếu Caesar không phải là rất an toàn?"
Vì vậy, trước, không ai muốn nói những gì các yếu Caesar?
[Sinh viên] Caesar Cipher chỉ là bạn có bản đồ, bạn chuyển tất cả thư,
một số lượng nhất định của các chữ cái đi qua, và di chuyển trên, và nó không phải là rất an toàn bởi vì
chỉ có 26 tùy chọn có thể, và bạn chỉ cần có cố gắng mỗi 1 trong những người cho đến khi bạn nhận được nó.
Oh. Vì vậy, tôi cần phải lặp lại?
Cơ yếu Caesar, it's - Ý tôi là, bạn sẽ đối phó với nó về những vấn đề mà bạn
Tôi đoán phiên bản tiêu chuẩn của tập vấn đề đó không phải là trên phiên bản hacker.
Vì vậy, phiên bản tiêu chuẩn để các thiết lập vấn đề, bạn nhận được một tin nhắn như, "thế giới, Xin chào",
và bạn cũng có một số giống như 6, và bạn đưa thông điệp đó, và mỗi nhân vật cá nhân,
bạn xoay nó bởi 6 vị trí trong bảng chữ cái.
Vì vậy, 'h' trong hello sẽ trở thành h-i-j-k-l-m-n.
Vì vậy, các chữ cái đầu tiên sẽ được n. Chúng tôi làm điều tương tự với e.
Nếu chúng ta có một, như, z hoặc một cái gì đó, sau đó chúng tôi quấn lại xung quanh 'một'.
Tuy nhiên, mỗi nhân vật được quay vòng 6 ký tự sau đó trong bảng chữ cái, và nó không phải rất an toàn
kể từ khi có chỉ có 26 khả năng có bao nhiêu cách bạn có thể bọc một lá thư duy nhất.
Vì vậy, bạn chỉ có thể thử tất cả 26 người trong số họ và, có lẽ, cho một tin nhắn đủ dài,
chỉ có 1 trong số những người 26 điều có thể là có được rõ ràng,
và rõ ràng là có được các thông báo ban đầu.
Vì vậy, nó không phải là một cách rất tốt mã hóa bất cứ điều gì ở tất cả.
Không liên quan đến những quần short, "một chức năng là gì?"
Vì vậy, một chức năng là gì? Vâng.
[Sinh viên] Nó giống như một mảnh riêng biệt của mã mà bạn có thể gọi để đi qua và sau đó nhận được giá trị trả lại bất cứ điều gì.
Yeah. Vì vậy, tôi sẽ trả lời bằng cách trả lời tiếp theo hoặc lặp lại bằng cách cũng chỉ trả lời tiếp theo.
Bạn có thể sử dụng chức năng thay vì chỉ cần sao chép và dán mã hơn và hơn một lần nữa.
Chỉ cần lấy mã, đặt nó vào một fuction, và sau đó bạn chỉ có thể gọi hàm
bất cứ nơi nào bạn đã được sao chép và dán.
Vì vậy, chức năng này là hữu ích.
Vì vậy, bây giờ chúng tôi sẽ làm vấn đề thực tế.
Người đầu tiên. Vì vậy, ý tưởng của một trong những đầu tiên là bạn vượt qua nó một chuỗi, và bất kể -
hoặc nó không nói tất cả các chữ thường? Nó không nói tất cả các chữ thường.
Vì vậy, các tin nhắn có thể được bất cứ điều gì, và - oh no. Nó không.
Để đơn giản, bạn có thể giả định rằng người sử dụng sẽ chỉ nhập vào chữ thường và không gian. "
Vì vậy, chúng tôi vượt qua nó một tin nhắn với các chữ thường và sau đó chúng tôi luân phiên
giữa tư bản và chữ thường - chúng tôi thay đổi chuỗi được vốn và chữ thường, xen kẽ.
Vì vậy, trước khi chúng tôi cung cấp cho bạn một thứ hai thậm chí nhảy vào vấn đề,
điều đầu tiên mà chúng ta cần làm là gì?
Ồ, tôi đã làm những gì chỉ cần nhấp vào? Oh, tôi chỉ nhấp vào một email ở đây.
Vì vậy, điều đầu tiên chúng ta cần làm - tôi đang tìm kiếm tại một sai lầm?
Đây có phải là một phần của một trong những điều này?
Không, những người vẫn còn ở trong đó, mặc dù.
Được rồi, vẫn ở đây.
Bây giờ chúng ta không thể giả định -? Vâng. Ở đây chúng ta không thể giả định rằng đó chỉ là chữ thường và không gian.
Vì vậy, bây giờ chúng tôi phải đối phó với thực tế rằng các ký tự có thể được bất cứ điều gì chúng tôi muốn họ được.
Và do đó, điều đầu tiên chúng tôi muốn làm là chỉ cần nhận được thông báo.
Chúng ta chỉ cần nhận được một chuỗi string s = GetString, okay.
Bây giờ vấn đề này, có một vài cách để làm nó.
Nhưng chúng ta sẽ muốn sử dụng Bitwise nhà khai thác ở đây.
Có những người hoặc là không phải ở các supersection,
hoặc một cái gì đó, và không biết những gì bitwise nhà khai thác?
Hoặc làm thế nào chúng liên quan đến ASCII trong bất kỳ cách nào?
[Sinh viên] Tôi không phải tại supersection, nhưng tôi biết những gì bitwise nhà khai thác.
Okay. Vì vậy, sau đó tôi không phải đi qua những căn bản của họ, nhưng tôi sẽ giải thích
những gì chúng ta sẽ muốn sử dụng ở đây.
Vì vậy, 'A': nhị phân đại diện vốn A, con số này là 65.
Tôi chỉ sẽ xem xét - 41 là có được 01.000.001.
Vì vậy, mà nên là 65 trong thập phân, vì vậy đây là biểu diễn nhị phân của các nhân vật vốn A.
Bây giờ, các biểu diễn nhị phân của nhân vật chữ thường 'a'
là có được điều tương tự, hầu như. Là - 6, yeah. Điều này là đúng.
Vốn Vì vậy, nhị phân, nhị phân chữ thường.
Vì vậy, nhận thấy rằng sự khác biệt giữa A và 'a' là bit duy nhất này.
Và điều này sẽ xảy ra là 32 bit, bit đại diện cho số 32.
Và điều đó làm cho tinh thần từ A là 65, 'a' là 97.
Sự khác biệt giữa chúng là 32.
Vì vậy, bây giờ chúng ta biết chúng ta có thể chuyển đổi từ A đến 'a' bằng cách lấy A
và bitwise ORing, trông giống như một 1.
Đây là một bitwise OR, với 00100000, mà sẽ cung cấp cho chúng tôi ".
Và chúng ta có thể nhận được từ 'a' đến A Bitwise ANDing
với 11, 0 ở nơi đó, 11.111.
Vì vậy, điều này sau đó sẽ cung cấp cho chúng tôi chính xác những gì 'a', nhưng hủy bỏ ra chút cá nhân,
vì vậy chúng ta sẽ có 01000001; Tôi không biết nếu tôi đếm đúng.
Nhưng kỹ thuật này bitwise ORing để có được từ vốn thành chữ thường,
và Bitwise ANDing để có được từ chữ thường vốn không phải là độc quyền A.
Tất cả các chữ cái, K vs k, Z vs z,
tất cả trong số họ chỉ sẽ khác nhau của thành viên này bit duy nhất.
Và như vậy bạn có thể sử dụng để thay đổi từ bất kỳ lá thư chữ thường cho bất kỳ bức thư vốn và ngược lại.
Okay. Vì vậy, một cách dễ dàng để nhận được từ này - vì vậy thay vì phải
viết ra bất cứ điều gì 1011111 - một cách dễ dàng đại diện cho con số này, và điều này không phải là một
mà tôi đã đi qua trong supersection, nhưng dấu ngã (~) là một nhà điều hành Bitwise.
~ Không là nó xem xét các đại diện bit.
Chúng ta hãy bất kỳ số lượng.
Đây chỉ là một số nhị phân, và những gì ~ không là nó chỉ là lật tất cả các bit.
Vì vậy, đây là một 1, bây giờ là 0, điều này là một số 0, bây giờ một 1, 010.100.
Vì vậy, đó là tất cả ~. Nên 32 là có được số lượng - có được thoát khỏi đó -
nên 32 sẽ là số 00.100.000, và như vậy ~ này là có được
con số này ở đây mà tôi ANDed 'a'.
Tất cả mọi người nhìn thấy không? Điều này là khá phổ biến, giống như khi bạn muốn tìm ra
cho những thứ sau này chúng ta có thể được nhìn thấy, khi chúng ta muốn xem nếu -
hay chúng ta muốn tất cả mọi thứ, tất cả các thiết lập bit duy nhất trừ 1
bạn có xu hướng để làm ~ của bit mà chúng ta không muốn đặt.
Vì vậy, chúng tôi không muốn các thiết lập 32 bit, do đó, chúng tôi ~ của 32.
Okay. Vì vậy, chúng ta có thể sử dụng tất cả những người ở đây.
Tất cả các quyền, vì vậy nó là tốt nếu bạn không thực hiện, chúng tôi sẽ từ từ đi bộ qua lại với nhau,
hoặc đi bộ qua này, vì vậy thông qua này. Đi bộ qua này.
Vì vậy, chúng tôi có chuỗi ký tự của chúng tôi, và chúng tôi muốn để lặp qua mỗi nhân vật trong chuỗi đó và làm điều gì đó với nó.
Vì vậy, làm thế nào để chúng tôi vòng qua một chuỗi? Những gì chúng tôi nên sử dụng?
Tôi sẽ không để làm điều đó ở đây. Yeah.
Vì vậy, tôi có iterator của tôi, và ông cho biết, nhưng làm thế nào để tôi biết bao nhiêu ký tự trong chuỗi?
Strlen (s), sau đó tôi + +.
Vì vậy, những gì tôi đã thực hiện ở đây không phải là cách tốt nhất để làm việc.
Có ai biết tại sao?
Bởi vì bạn đang kiểm tra ngôn ngữ của chuỗi mỗi lần duy nhất.
Vì vậy, chúng ta sẽ muốn di chuyển strlen, tôi có thể nói lên ở đây, int length = strlen (s),
và sau đó làm i <chiều dài, và trong trường hợp bạn đã không nhìn thấy nó trước,
Tôi cũng có thể làm int i = 0, chiều dài = strlen (s).
Và do đó, điều này có phần thích hợp hơn, kể từ bây giờ tôi đã hạn chế phạm vi
của chiều dài biến chỉ cần 'cho' vòng lặp này, thay vì tuyên bố nó trước khi
và nó luôn luôn tồn tại, và trong trường hợp bạn đã không bắt được lý do tại sao đó là xấu,
hoặc lý do tại sao ban đầu là xấu, it's - bắt đầu cho vòng lặp.
Tôi đã kiểm tra điều kiện. I <độ dài của s?
Vì vậy, độ dài của s, chúng ta hãy làm việc với "hello" toàn bộ thời gian.
Vì vậy, chiều dài của s, h-e-l-l-o. Chiều dài là 5.
Vì vậy, i = 0, chiều dài là 5, vì vậy tôi không phải là <5, do đó, vòng lặp tiếp tục.
Sau đó, chúng tôi đi một lần nữa. Chúng tôi kiểm tra điều kiện. I <chiều dài của hello?
Vì vậy, hãy kiểm tra độ dài của hello. H-e-l-l-o. Đó là 5, tôi không phải là <5, vì vậy chúng tôi tiếp tục một lần nữa.
Vì vậy, chúng tôi đang tính toán, chúng tôi đang đếm chào, mỗi lần lặp của vòng lặp,
thậm chí nghĩ rằng nó không bao giờ thay đổi, nó luôn luôn là 5.
Vì vậy, chúng tôi chỉ cần nhớ 5 lên phía trước, và bây giờ mọi thứ tốt hơn.
Vì vậy, iterating trên toàn bộ chuỗi.
Chúng ta muốn gì để làm cho mỗi ký tự của chuỗi?
[Sinh viên nói, khó hiểu]
Yeah. Vì vậy, nếu nhân vật này là không thuộc chữ cái, sau đó chúng tôi chỉ muốn bỏ qua nó.
Bởi vì chúng tôi chỉ quan tâm đến chữ chữ cái, chúng ta không thể tận dụng một số.
Vì vậy, làm thế nào chúng ta có thể làm điều này? Vì vậy, điều kiện của chúng tôi, vì vậy nếu chúng ta muốn một cái gì đó - kiểm tra nếu nó là chữ cái.
Vì vậy, làm thế nào để chúng ta kiểm tra này?
[Sinh viên] Bạn chỉ có thể sử dụng chức năng là alpha.
Là bao gồm trong một trong những, hoặc bất kỳ bao gồm như thế, char.h hoặc một cái gì đó?
Hãy sử dụng alpha chức năng, và sử dụng rõ ràng - vì vậy chúng tôi có s [i],
là nhân vật thứ tám của s, hãy nhớ rằng một chuỗi là một mảng kí tự,
do đó, nhân vật thứ tám của s.
Bây giờ, nếu nó là một bức thư vốn, chúng ta biết nó có phải là trong một phạm vi cụ thể.
Và phạm vi đó là gì?
Yeah. Vì vậy, nếu s [i] là ≥ 65, và s [i] là ≤ 90, tôi nên làm gì thay vì?
Yeah. Vì vậy, bạn nên tuyệt đối không bao giờ cần phải biết giá trị ASCII của bất cứ điều gì bao giờ.
Đừng bao giờ nghĩ rằng trong số 65 số, 90, 97 và 102, hoặc bất cứ điều gì nó là.
Bạn không cần - 112 - bạn không cần phải biết những người ở tất cả? Đó là sai quá.
Chỉ sử dụng các ký tự single-quote, các hằng số báo duy nhất. Vì vậy, 'A' và ít hơn 90 Z.
Và đây là tốt hơn đáng kể - Tôi sẽ không biết ra khỏi đỉnh đầu của tôi rằng Z là 90.
Tôi không biết ra khỏi đỉnh đầu của tôi rằng 'Z' là vốn Z.
Vì vậy, miễn là điều này là trong phạm vi của vốn vốn Z, hoặc chúng tôi có thể kiểm tra chữ thường,
Hoặc nếu đó là trong phạm vi ≥ 'a' và ≤ z.
Vì vậy, đó là điều kiện của chúng tôi.
Các phong cách cho các nơi để đưa những điều khác nhau.
Tôi sẽ làm điều đó như thế này.
Bây giờ, những gì chúng ta muốn làm gì?
Chúng tôi biết lá thư này là một nhân vật, một ký tự chữ cái.
Vì vậy, chúng ta cần phải luân phiên giữa liệu điều này, nên có một bức thư vốn hoặc một lá thư chữ thường.
Làm thế nào để chúng ta theo dõi một trong số đó, chúng tôi muốn nó được?
[Sinh viên tiếng nói, không thể hiểu]
Vì vậy, có, nhưng hãy để tôi kiểm tra.
Mô-đun 0-2 đã nói, là một gợi ý ném ra, và tôi đồng ý với điều đó.
Ngoại trừ thông báo rằng, giống như là trường hợp? Yeah.
Mỗi khác, nhưng chúng ta không thể module 2 của tôi, hoặc mod i 2, kể từ khi
nhận thấy rằng E là vốn và 'a' là chữ thường? Nhưng có một không gian tách biệt chúng?
Vì vậy, họ sẽ cùng các mod 2, nhưng họ là những trường hợp khác nhau.
[Sinh viên câu hỏi, không thể hiểu]
Yeah. Vì vậy, chúng tôi chỉ cần đi để giữ một số.
Chúng tôi cũng có thể làm điều đó ở đây nếu chúng ta muốn, mà có thể có được một chút khó sử dụng
trong vòng lặp cho các tờ khai; tôi sẽ đưa nó lên đây.
Vì vậy, int count = bắt đầu từ 0.
Và vì vậy bây giờ tôi sẽ đếm có bao nhiêu ký tự chữ cái chúng ta đã có.
Vì vậy, chúng tôi chắc chắn sẽ để đếm + + kể từ khi chúng tôi tìm thấy một chữ cái khác.
Tuy nhiên, vì vậy bây giờ bạn đang nói rằng nếu số đếm mod 2.
Vì vậy, những gì nếu số đếm mod 2? Oh. Tôi sẽ làm == 0 cho bây giờ.
Chúng tôi cũng sẽ đi qua đó. Vì vậy, nếu đếm mod 2 == 0, sau đó những gì?
[Sinh viên câu trả lời, không thể hiểu]
Vì vậy, chúng tôi muốn nó kết thúc chữ hoa.
Có 2 trường hợp, hoa và chữ thường là 2 trường hợp.
Vì vậy, nếu chúng ta đang ở dạng chữ thường chúng ta cần để làm cho nó thành chữ hoa.
Nếu đó là chữ hoa, chúng tôi không cần phải làm bất cứ điều gì.
Tuy nhiên, có một cách - shouldn't đã lộn -
mà chúng ta thậm chí không cần phải kiểm tra xem nó là chữ hoa hoặc chữ thường?
Những gì chúng tôi có thể làm gì để luôn luôn đảm bảo rằng chúng tôi luôn luôn kết thúc ở chữ hoa?
Vì vậy, nhận thấy những gì chúng tôi đã làm cho chữ thường 'a', nếu chúng ta đã làm cùng một điều này chính xác chữ hoa A?
Có chữ hoa Một sự thay đổi, hoặc không thay đổi giá trị?
Yeah. Vì vậy, bất kỳ bức thư vốn bitwise ANDed với ~ 32 là có được rằng nhân vật cùng một chữ hoa
bởi vì đối với bất kỳ ký tự chữ hoa bit 32 không được thiết lập.
Vì vậy, nếu chúng ta muốn phải đưa nhân vật s [i], chúng tôi muốn nó trở thành chữ thường hoặc chữ hoa.
Vì vậy, nếu nó là chữ thường, bây giờ là chữ hoa, nếu nó đã được viết hoa, nó vẫn còn chữ hoa, và đó là nó.
Tôi đã nói điều này trong các supersection: Bạn có thể sử dụng 32 nếu bạn muốn, nhưng tôi có xu hướng thích làm 'a' - A,
thay vì chỉ đơn giản 32, bởi vì nó có thể là bất kỳ bit khác.
Sau khi 32 bit, nó có thể là bất kỳ trong số này, hoặc chúng tôi sẽ không có đủ
con số đại diện cho tất cả các nhân vật.
Vì vậy, nếu bạn nhận được 32 bit, nó có thể là 64 bit, nó có thể là 128 bit.
Bất kỳ của các bit có thể là bit phân biệt giữa chữ hoa và chữ thường.
Tôi không nên cần phải biết rằng đó là 32 bit.
Tôi có thể sử dụng 'a' - A để có được các bit khác nhau giữa hai
mà không cần phải dựa vào con số kỳ diệu đó là 32.
Và vì vậy bây giờ, khác tính thật kỳ quặc, và do đó, những gì tôi muốn làm?
[Câu trả lời của sinh viên, không thể hiểu]
[Sinh viên] đó là gì?
Tôi sẽ làm điều đó trong 1 giây.
Vì vậy, bây giờ nếu tôi muốn - tôi muốn chắc chắn rằng nhân vật này là chữ thường,
và vì vậy tôi có thể hoặc 32, và 'a' 32 ý nghĩa - A.
Nhưng chú ý, bởi cùng một lý do là trước đó, rằng nếu
lá thư đã chữ thường, sau đó ORing của 32 chỉ giữ nó thành chữ thường.
Nó đã không thay đổi các ký tự ban đầu.
Nhưng bây giờ tôi không cần phải tránh nói rằng, "Nếu nó là chữ thường, chỉ cần quên nó đi,
nếu nó là chữ hoa, sau đó thay đổi nó. "
Đó là thuận tiện hơn nhiều để làm điều này.
[Sinh viên] rằng chiến lược của trừ chữ hoa chữ thường từ công việc nếu nó không được 32?
Nếu nó là, như, 34 hoặc một cái gì đó?
Vì vậy, bạn cần phải biết rằng sự khác biệt giữa 2? >> 1 bit.
Nó có thể là nhiều hơn 1 bit, miễn là tất cả các bit dưới vị trí này là như nhau.
Vì vậy, chúng ta cần ít nhất 26 ký tự - hoặc, có 26 ký tự.
Vì vậy, chúng ta cần ít nhất 26 số để đại diện cho sự khác biệt -
Sự khác biệt giữa A và 'a' có được ít nhất là 26,
nếu không chúng ta sẽ không có đại diện tất cả các số vốn.
Điều đó có nghĩa là A, nếu chúng ta bắt đầu từ 1, nó sẽ sử dụng tất cả các bit,
tất cả của 5 bit đầu tiên, đại diện cho tất cả mọi thứ thông qua Z.
Đó là lý do tại sao các bit tiếp theo, hoặc bit này, các bit tiếp theo là một trong đó là lựa chọn để phân biệt giữa A và 'a'.
Đó cũng là lý do tại sao, trong bảng mã ASCII, có 5 biểu tượng tách chữ hoa chữ thường.
Kể từ khi những người đang có những biểu tượng, thêm 5 sẽ trả số 32 là sự khác biệt giữa chúng.
[Sinh viên] Vì vậy, chúng ta có thể làm điều đó, bởi vì ASCII thiết kế như vậy.
Vâng. Nhưng ASCII - sự khác biệt cũng có thể được cả hai của các bit.
Giống như, nếu A là 10000001, và 'a' là 11100001 - tôi quên, bất cứ điều gì.
Nhưng nếu nó đã được điều này, thì chúng ta vẫn có thể sử dụng 'a' - A.
Nó chỉ là sự khác biệt giữa A và 'a' vẫn còn 2 bit này.
Tôi nghĩ rằng nó được viết bằng 48. Có 32 + 64? Tôi nghĩ rằng đó là?
Nó vẫn sẽ là 2 bit, tất cả các nhân vật duy nhất, như, Z và z, K và k,
họ vẫn sẽ có các bit chính xác cùng trừ 2 bit.
Vì vậy, miễn là đó là luôn luôn đúng, bất kể nếu chúng ta đang sử dụng ASCII hoặc một số hệ thống khác,
miễn là chỉ có một số thiết lập của các bit khác nhau cho mỗi ký tự,
sau đó hoạt động tốt.
Nó chỉ là 32 bit đã được thiết lập bởi vì đó là một trong những đầu tiên chúng ta có thể có thể sử dụng. >> Cool.
Tôi có xu hướng thích, trong trường hợp bạn không nhìn thấy, nếu khối là chỉ có một đường duy nhất,
bạn có thể nhận được thoát khỏi dấu ngoặc nhọn, vì vậy tôi có xu hướng thích làm điều này.
Ngoài ra, bạn biết làm thế nào chúng ta có thể làm những việc như s [i] + = 1?
Bạn cũng có thể làm s [i] phép toán AND = 32.
Và bitwise OR = 32.
Ngoài ra, đếm mod 2 == 0.
Vì vậy, hãy nhớ rằng tôi sẽ không viết bất kỳ giá trị nào khác không là đúng, và 0 là sai.
Vì vậy, "nếu số đếm mod 2 == 0" là giống như nói rằng "nếu không tính mod 2."
Tôi có lẽ sẽ chỉ cần đảo ngược các dòng và nói, "nếu số đếm mod 2,
làm các việc OR 1, người khác làm những VÀ 1 ", vì vậy mà tôi không cần" không ".
Nhưng công trình này chỉ là tốt.
Và những gì khác tôi có thể làm ở đây?
Bạn có thể kết hợp chúng với ternary nếu bạn muốn, nhưng sau đó mà chỉ muốn làm cho mọi thứ hỗn độn
và có lẽ khó khăn hơn để đọc, vì vậy chúng tôi sẽ không làm điều đó.
Bất cứ ai có bất cứ lời đề nghị khác?
Rằng tất cả các vấn đề yêu cầu? Oh yeah.
Vì vậy, để loại bỏ những dòng trống, bây giờ chúng tôi sẽ in f,% s là một chuỗi,
Chúng tôi sẽ in f, s.
Bây giờ chúng ta hãy chạy nó. Tôi đã làm gì sai?
Đó là một \ ", tôi muốn có một n.
Okay. Bây giờ chúng ta sẽ chạy nó. Nó có thể sẽ hét lên với tôi.
Strlen là trong string.h.
Vì vậy, đây là điều tốt đẹp về Clang là nó sẽ cho bạn những gì nó có trong,
thay vì GCC mà chỉ cần nói: "Này, bạn quên một cái gì đó, tôi không biết nó là cái gì."
Nhưng điều này sẽ cho tôi biết, "Bạn có nghĩa là bao gồm string.h".
Vì vậy, tôi đã không nhắc nhở cho bất cứ điều gì, vì vậy nó không nói bất cứ điều gì.
Nhưng chúng tôi sẽ làm ví dụ của họ, "Cảm ơn 4 tiện ích".
Điều đó có vẻ đúng. Hoan hô.
Vì vậy, trở lại chính của bạn, tôi gần như không bao giờ làm điều đó.
Đó là tùy chọn. Và chính là chức năng duy nhất đó là tùy chọn.
Nếu bạn không trả lại bất cứ điều gì từ chính, nó giả định rằng bạn có nghĩa là để trở về 0.
Câu hỏi?
Okay. Vì vậy, bây giờ vấn đề thứ hai.
"Xem lại từ bài giảng thứ hai tuần 2 trao đổi giá trị của 2 biến bằng cách đi qua
những 2 biến đến một chức năng (thậm chí nếu gọi là swap) không chính xác làm việc, ít nhất là không phải không có con trỏ. "
Và bỏ qua con trỏ cho đến khi chúng tôi nhận được cho họ.
Chúng tôi muốn trao đổi 2 biến, chúng tôi không sử dụng một chức năng để làm điều đó.
Chúng tôi vẫn sẽ làm điều đó trong chính như nó nói.
Nhưng để sử dụng 2 biến, chúng tôi không muốn sử dụng một biến tạm thời.
Có 2 cách để làm điều này.
Bạn có thể làm điều đó bằng cách sử dụng các nhà điều hành nhị phân truyền thống của bạn.
Vì vậy, không ai biết một cách nhanh chóng và bẩn làm điều đó?
Nó thực sự có thể mất một phút suy nghĩ. Nếu tôi có -
Tôi sẽ đặt vấn đề như họ yêu cầu. Vì vậy, nếu tôi có 2 biến, A, chỉ là một số nguyên
họ cung cấp cho tôi, và B biến Tóm lại, đó là một số nguyên mà tôi cho.
Vì vậy, nếu tôi có 2 biến này, bây giờ tôi muốn trao đổi chúng.
Truyền thống, sử dụng toán tử nhị phân thường xuyên của bạn, tôi có nghĩa là, như +, -, ÷.
Không Bitwise điều hành hoạt động nhị phân.
Vì vậy, bằng cách sử dụng -, +, ÷, và tất cả những người.
Chúng tôi có thể trao đổi bằng cách làm một cái gì đó giống như a = a + b, và b = a - b, a = a - b.
Vì vậy, sự tỉnh táo kiểm tra, và sau đó chúng ta sẽ thấy lý do tại sao mà các công trình.
Hãy nói rằng = 7, b = 3, sau đó a + b sẽ là 10.
Vì vậy, chúng tôi đang thiết lập một 10 =, và sau đó chúng tôi đang làm b = a - b.
Vì vậy, chúng tôi đang làm b = a - b, đó là sẽ là 7, và b = a - b một lần nữa,
hoặc a = a - b. Đó là sẽ là 10 - 7 là 3.
Vì vậy, bây giờ, một cách chính xác, 'a' là 7, b là 3, và bây giờ b 7 và 'a' là 3.
Vì vậy, loại đó có ý nghĩa; 'a' là sự kết hợp của 2 con số.
Tại thời điểm này, 'a' là sự kết hợp, và sau đó chúng ta trừ đi b ban đầu,
và sau đó chúng ta trừ đi ra ban đầu là 'a'.
Nhưng điều này không làm việc cho tất cả các số.
Để thấy điều này, chúng ta hãy xem xét một hệ thống, vì thế chúng ta thường nghĩ các số nguyên như 32 bit.
Hãy làm việc trên một cái gì đó chỉ giống như 4 bit.
Hy vọng rằng tôi đến với một ví dụ tốt ngay bây giờ.
Vì vậy, tôi biết, điều này sẽ dễ dàng.
Hãy nói rằng 2 của chúng tôi số là 1111, và 1111, vì vậy chúng tôi trong hệ nhị phân ngay bây giờ.
Trong số thập phân thực tế, nếu bạn muốn nghĩ về nó theo cách đó, một = 15 và b = 15
Và vì vậy chúng tôi hy vọng, sau khi chúng tôi trao đổi chúng - họ thậm chí không phải là những con số tương tự,
nhưng tôi đã làm nó theo cách này.
Hãy làm cho họ không phải là những con số tương tự. Hãy làm 1111 và 0001.
Vì vậy, một = 15 và b = 1.
Sau khi chúng tôi trao đổi chúng, chúng tôi hy vọng 'a' là 1 và b là 15.
Vì vậy, bước đầu tiên của chúng tôi là a = a + b.
Số lượng của chúng tôi là chỉ có 4 bit rộng, do đó, 'a' là 1111, + b, đó là 0001,
sẽ kết thúc được 10.000, nhưng chúng tôi chỉ có 4 bit.
Vì vậy, bây giờ a = 0.
Và bây giờ chúng tôi muốn thiết lập b = a - b - trên thực tế, điều này vẫn còn hoạt động ra hoàn hảo.
= a - chúng ta hãy xem nếu điều này hoạt động ra hoàn hảo - b.
Vì vậy, sau đó b = 0 - 1, mà vẫn sẽ là 15, và sau đó a = a - b, đó sẽ là 1.
Có lẽ điều này không làm việc.
Tôi cảm thấy như có một lý do nó không hoạt động sử dụng thường xuyên.
Được rồi, do đó, làm việc trên giả định rằng nó không làm việc với các hoạt động nhị phân thường xuyên,
và tôi sẽ tìm kiếm - Google để xem nếu đó là sự thật.
Vì vậy, chúng tôi muốn làm điều đó bằng cách sử dụng Bitwise nhà điều hành, và các đầu mối ở đây là XOR.
Vì vậy, giới thiệu XOR (^) nếu bạn không nhìn thấy nó.
Đó là, một lần nữa, một nhà điều hành Bitwise vì vậy nó hoạt động từng chút từng chút, và it's
Nếu bạn có các bit 0 và 1, sau đó sẽ được 1.
Nếu bạn có bit 1 và 0, nó sẽ là 1, bạn có 0 bit và 0 nó sẽ là 0,
và nếu bạn có bit 1 và 1 nó sẽ là 0.
Vì vậy, nó như OR. Nếu một trong các bit là đúng sự thật, đó là 1, nhưng không giống như OR, nó không thể là cả hai bit là đúng sự thật.
OR sẽ là 1, XOR này là 0.
Vì vậy, chúng ta sẽ muốn sử dụng XOR đây.
Hãy suy nghĩ về nó trong một phút, tôi sẽ đến Google.
Vâng, bạn không thể đọc rằng, tôi là hiện nay trên trang XOR các thuật toán trao đổi.
Hy vọng rằng điều này sẽ giải thích lý do tại sao tôi không thể nào -
Đây chính là thuật toán mà chúng ta chỉ cần làm.
Tôi vẫn không thấy lý do tại sao tôi phải có chỉ chọn một ví dụ xấu,
nhưng trường hợp này 'a' đã xảy ra để trở thành 0, sau khi nhận được đến 5 bit, vì vậy bây giờ 'a' là 0,
đó là những gì được gọi là "số nguyên tràn".
Theo Wikipedia, "Không giống như các trao đổi XOR, sự thay đổi này đòi hỏi sử dụng một số phương pháp
để đảm bảo rằng x + y không gây ra một tràn số nguyên. "
Vì vậy, điều này không có vấn đề, đây là số nguyên tràn, nhưng tôi đã làm gì đó sai trái.
Tôi không chắc. Tôi sẽ cố gắng để đến với một số khác.
[Sinh viên], không phải là số nguyên tràn khi bạn đang cố gắng để đặt một số trong đó
lớn hơn số bit bạn đã phân bổ?
Yeah. Chúng tôi có 4 bit. Đó - chúng tôi đã có 4 bit, sau đó chúng tôi cố gắng thêm 1 đến nó, vì vậy chúng tôi kết thúc với 5 bit.
Tuy nhiên, các bit thứ năm chỉ bị cắt, yeah.
Nó có thể thực sự -
[Sinh viên] mà ném cho bạn một lỗi, hoặc nào đó - đó sẽ ném ra một lỗi?
Số Vì vậy, không có lỗi. Khi bạn nhận được đến cấp độ lắp ráp, một chút đặc biệt
một nơi nào đó được thiết lập cho biết đã có một tràn, nhưng trong C bạn loại không đối phó với điều đó.
Bạn thực sự không thể đối phó với nó, trừ khi bạn sử dụng các hướng dẫn lắp ráp đặc biệt trong C.
Hãy suy nghĩ về trao đổi XOR.
Và tôi nghĩ rằng các bài viết Wikipedia cũng có thể nói rằng -
Vì vậy, nó cũng đưa ra số học modula, vì vậy tôi đoán tôi đã, trong lý thuyết, làm số học mô-đun
khi tôi nói rằng 0 - 1 là 15 một lần nữa.
Vì vậy mà có thể thực sự - một bộ xử lý thường xuyên mà không 0 - 1 = 15.
Kể từ khi chúng tôi kết thúc ở 0, chúng ta trừ đi 1, do đó, sau đó nó chỉ kết thúc tốt đẹp trở lại khoảng 1111.
Vì vậy, thuật toán này thực sự có thể làm việc, a + b, a - b, b - a, mà có thể được sử dụng tốt.
Nhưng có một số bộ vi xử lý mà không làm điều đó, và vì vậy nó sẽ không được sử dụng tốt trong những những người cụ thể.
XOR trao đổi này sẽ làm việc trên bất kỳ bộ vi xử lý. Okay.
Ý tưởng là nó phải là như vậy, mặc dù.
Nơi mà chúng tôi đang sử dụng XOR bằng cách nào đó có được các thông tin của cả hai vào 1 trong các biến,
và sau đó kéo ra các thông tin của các biến cá nhân một lần nữa.
Vì vậy, không ai có ý tưởng / câu trả lời?
[Sinh viên câu trả lời, không thể hiểu]
Vì vậy, nên làm việc này, và cũng có thể, XOR là giao hoán.
Bất kể đó để 2 số này xảy ra được ở đây,
kết quả này là có được như vậy.
Vì vậy, một ^ b là b ^ a.
Bạn cũng có thể thấy điều này bằng văn bản như a ^ = b, b ^ = a, a ^ = b một lần nữa.
Vì vậy, điều này là đúng, và để xem lý do tại sao các công trình này, suy nghĩ của các bit.
Sử dụng một số smallish, chúng ta hãy nói 11.001, và 01.100.
Vì vậy, đây là 'a', đây là b.
Vì vậy, một ^ = b.
Chúng ta sẽ được thiết lập = 'a' XOR của 2 điều này.
Vì vậy, 1 ^ 0 là 1, 1 ^ 1 là 0, 0 ^ 1 là 1, và 0 ^ 0 là 0, 1 ^ 0 là 1.
Vì vậy, ',' nếu bạn nhìn vào số thập phân, nó sẽ được -
bạn sẽ không thấy nhiều của một mối quan hệ giữa bản gốc 'a' và mới ','
nhưng nhìn vào các bit, 'a' bây giờ là giống như một mạng lưới thông tin
cả hai bản gốc 'a' và b ban đầu.
Vì vậy, nếu chúng ta lấy b ^ a, chúng ta thấy rằng chúng tôi sẽ kết thúc tại một.
Và nếu chúng ta lấy bản gốc 'a' mới ', chúng ta thấy chúng ta kết thúc tại b ban đầu.
Vì vậy, (a ^ b) ^ b = gốc.
Và (a ^ b) ^ a = b ban đầu.
Có một cách khác để nhìn thấy điều này là bất cứ điều gì XOR chính nó luôn luôn là 0.
Vì vậy, 1101 ^ 1101, tất cả các bit sẽ là như vậy.
Vì vậy, sẽ không bao giờ là một trường hợp trong đó 1 là 0 và sự khác 1.
Vì vậy, đây là 0000.
Cùng với điều này. (A ^ b) ^ b giống như một ^ (b ^ b).
(B ^ b) sẽ là 0 ^ 0 là chỉ cần đi là 'a', vì tất cả các bit là 0.
Vì vậy, những người duy nhất đang có được nơi 'a' ban đầu là 1 - có những người thân.
Và cùng một ý tưởng ở đây, tôi khá chắc chắn rằng nó cũng giao hoán.
Yeah. Tôi đã nói trước rằng đó là giao hoán.
^ ',' Và đó là kết hợp, vì vậy bây giờ (b ^ a) ^ a.
Và chúng ta có thể làm b ^ (a ^ a).
Và như vậy một lần nữa, chúng tôi nhận b ban đầu.
Vì vậy, 'a' bây giờ là sự kết hợp của 'a' và b với nhau.
Sử dụng combo mới của chúng tôi "chúng ta nói b = combo một '^ b ban đầu, chúng tôi nhận được bản gốc.
Và một combo = 'a' ^ b, là bản gốc hoặc bây giờ là 'a' hoặc b là những gì.
Đó là trường hợp này đây. Đây là = b, b cũ.
Vì vậy, bây giờ tất cả mọi thứ trở lại theo thứ tự trao đổi.
Nếu chúng ta thực sự nhìn vào các bit, b = a ^ b, sẽ XOR những 2,
và câu trả lời là có được điều này, và sau đó a = a ^ b XORing những 2 và câu trả lời là điều này.
Câu hỏi? Okay. Vì vậy, cuối cùng là một chút khó khăn hơn đáng kể.
[Sinh viên] Tôi nghĩ rằng ông đã có một câu hỏi về nó. >> Ồ, xin lỗi.
[Sinh viên] Điều gì thực sự nhanh hơn? Nếu bạn sử dụng XOR này, hoặc là nó nếu bạn khai báo một biến mới?
Vì vậy, những gì là thực sự nhanh hơn, khai báo một biến mới hoặc sử dụng XOR để trao đổi?
Câu trả lời là, trong tất cả các khả năng, một biến tạm thời.
Và đó là bởi vì một khi nó được biên dịch xuống - vì vậy ở mức độ lắp ráp,
không có những điều như biến địa phương hoặc bất kỳ biến tạm thời hoặc bất kỳ công cụ này.
Họ giống như có bộ nhớ, và có đăng ký.
Đăng ký là nơi mà mọi thứ đang tích cực xảy ra.
Bạn không thêm 2 điều trong bộ nhớ, bạn thêm 2 điều trong sổ đăng ký.
Và bạn mang lại những điều từ bộ nhớ vào sổ đăng ký sau đó thêm chúng,
và sau đó bạn có thể đặt chúng trở lại vào bộ nhớ, nhưng tất cả các hành động xảy ra trong sổ đăng ký.
Vì vậy, khi bạn đang sử dụng phương pháp biến tạm thời, thường là những gì xảy ra là
2 con số này đã có trong sổ đăng ký.
Và sau đó từ thời điểm đó, sau khi bạn đã đổi chỗ,
nó sẽ chỉ bắt đầu sử dụng sổ đăng ký khác.
Bất cứ nơi nào bạn đã sử dụng b, nó sẽ chỉ sử dụng sổ đăng ký đã được lưu trữ một '.
Vì vậy, nó không cần phải làm bất cứ điều gì để thực sự làm hoán đổi. Yeah?
[Sinh viên] Nhưng nó cũng phải mất nhiều bộ nhớ hơn, phải không?
Nó sẽ chỉ mất nhiều bộ nhớ hơn nếu nó cần để lưu trữ biến tạm thời.
Cũng giống như nếu sau này bạn sử dụng biến tạm thời một lần nữa một nơi nào đó,
sau đó - bạn chỉ định một cái gì đó để mà biến tạm thời.
Vì vậy, nếu tại bất kỳ điểm nào trong thời gian ',' b ở nhiệt độ có giá trị riêng biệt hoặc một cái gì đó,
sau đó nó sẽ có vị trí khác nhau trong bộ nhớ, nhưng nó là sự thật
có rất nhiều biến địa phương đó sẽ chỉ tồn tại trong sổ đăng ký.
Trong trường hợp đó, nó không bao giờ đặt vào bộ nhớ, và do đó bạn sẽ không bao giờ lãng phí bộ nhớ.
Okay. Câu hỏi cuối cùng là một chút.
Vì vậy, ở đây, thiết bị này CS50, có một từ điển.
Và lý do cho điều này là bởi vì [? B66?] Là một kiểm tra chính tả nơi bạn sẽ được viết
bằng cách sử dụng bảng băm hoặc cố gắng hoặc cấu trúc một số dữ liệu.
Bạn đang đi để được viết một kiểm tra chính tả, và bạn sẽ được sử dụng từ điển này để làm điều đó.
Nhưng đối với vấn đề này, chúng tôi chỉ cần đi để tìm kiếm để xem nếu một từ duy nhất có trong từ điển.
Vì vậy, thay vì lưu trữ toàn bộ từ điển trong một số cấu trúc dữ liệu
và sau đó nhìn trên toàn bộ tài liệu để xem nếu bất cứ điều gì sai chính tả,
chúng tôi chỉ muốn tìm 1 từ. Vì vậy, chúng tôi chỉ có thể quét qua toàn bộ từ điển
và nếu chúng ta không bao giờ tìm thấy từ trong từ điển, sau đó nó là không ở trong đó.
Nếu chúng ta quét qua toàn bộ từ điển và tôi thấy từ, sau đó chúng tôi đang tốt, chúng tôi tìm thấy nó.
Nó nói ở đây là chúng tôi muốn bắt đầu tìm kiếm chức năng xử lý tập tin của C,
kể từ khi chúng tôi muốn đọc từ điển,
nhưng tôi sẽ cung cấp cho các gợi ý ở đây là chức năng mà bạn nên nghĩ đến.
Tôi sẽ viết chúng trên Spaces.
Vì vậy, những người chủ yếu bạn sẽ muốn để nhìn được f mở và sau đó, chắc chắn, f đóng cửa,
mà sẽ đi vào cuối của chương trình của bạn, và f f quét.
Bạn cũng có thể sử dụng e đọc, nhưng có thể bạn không muốn
bởi vì đó - bạn không kết thúc cần rằng.
F quét f là những gì bạn sẽ được sử dụng để quét qua từ điển.
Và như vậy bạn không cần phải mã lên các giải pháp, chỉ cần cố gắng và thích giả mã theo cách của bạn
một giải pháp, và sau đó chúng tôi sẽ thảo luận về nó.
Và trên thực tế, kể từ khi tôi đã đưa cho bạn những, nếu bạn đi vào bất kỳ thiết bị đầu cuối hoặc vỏ của thiết bị của bạn,
Tôi sẽ - Tôi thường - nếu bạn không nhìn thấy, tôi không biết nếu bạn đã làm trong lớp học,
nhưng người đàn ông, do đó, các trang con người, là khá hữu ích để xem xét chức năng khá nhiều bất kỳ.
Vì vậy, tôi có thể làm, như, người đàn ông f, quét f.
Đây là các thông tin về gia đình f quét các chức năng.
Tôi cũng có thể làm e người đàn ông, mở, và đó sẽ cung cấp cho tôi các chi tiết của điều đó.
Vì vậy, nếu bạn biết chức năng bạn đang sử dụng, hoặc bạn đang đọc mã
và bạn thấy một số chức năng và bạn đang như thế, "làm gì?"
Chỉ cần người đàn ông đó tên hàm.
Có một vài ví dụ kỳ lạ, nơi bạn có thể phải nói
muốn. man 2 tên hàm, hay người đàn ông 3 tên hàm đó,
nhưng bạn chỉ có để làm điều đó nếu tên người đàn ông chức năng không xảy ra để làm việc lần đầu tiên.
[Sinh viên] Vì vậy, tôi đang đọc trang người đàn ông cho mở, nhưng tôi vẫn còn lẫn lộn về làm thế nào để sử dụng nó và chương trình.
Okay. Rất nhiều các trang người đàn ông ít hơn hữu ích.
Chúng hữu ích hơn nếu bạn đã biết những gì họ làm
và sau đó bạn chỉ cần phải nhớ thứ tự của các đối số hoặc một cái gì đó.
Hoặc họ có thể cung cấp cho bạn một tổng quan chung, nhưng một số người trong số họ là rất áp đảo.
Giống như e f quét, cũng. Nó cung cấp cho bạn những thông tin cho tất cả các chức năng này,
và 1 dòng xuống đây sẽ xảy ra để nói, "F quét f đọc từ điểm chuỗi hoặc dòng."
Nhưng e mở. Vì vậy, làm thế nào chúng ta sẽ sử dụng e mở?
Ý tưởng của một chương trình mà cần phải làm tập tin I / O là
trước tiên bạn cần để mở các tập tin bạn muốn làm việc với, và chắc chắn,
đọc những điều từ tập tin đó và làm công cụ với họ.
F mở là những gì chúng tôi sử dụng để mở các tập tin.
Điều chúng tôi nhận được trở lại, do đó, những tập tin nào chúng tôi muốn mở, nó cho chúng ta -
ở đây nó nói "/ user / share / dict / words".
Đây là tập tin mà chúng tôi muốn mở, và chúng tôi muốn để mở nó -
chúng tôi có chỉ định rõ ràng cho dù chúng tôi muốn mở nó để đọc hoặc nếu chúng tôi muốn mở nó để viết.
Có một vài kết hợp và các công cụ, nhưng chúng tôi muốn mở này để đọc.
Chúng tôi muốn đọc từ tập tin.
Vì vậy, trở lại này không những gì? Nó trả về một ngôi sao tập tin (*),
và tôi sẽ chỉ hiển thị tất cả mọi thứ trong biến f, *,
một lần nữa, nó là một con trỏ, nhưng chúng tôi không muốn để đối phó với con trỏ.
Bạn có thể nghĩ của f, f là biến bạn đang sử dụng để đại diện cho các tập tin.
Vì vậy, nếu bạn muốn đọc từ tập tin, bạn đọc từ f.
Nếu bạn muốn đóng các tập tin, bạn đóng f.
Vì vậy, vào cuối của chương trình khi chúng tôi chắc chắn muốn đóng các tập tin, những gì chúng ta nên làm gì?
Chúng tôi muốn đóng f.
Vì vậy, bây giờ là chức năng tập tin cuối cùng mà chúng ta sẽ muốn sử dụng là quét f, f quét f.
Và những gì mà không là nó quét qua các tập tin tìm kiếm một mô hình cho phù hợp.
Nhìn vào trang người đàn ông ở đây, chúng ta thấy int f quét f, bỏ qua giá trị trả lại cho bây giờ.
Đối số đầu tiên là tập tin * dòng, do đó, đối số đầu tiên chúng ta sẽ muốn vượt qua là f.
Chúng tôi đang quét qua f.
Số thứ hai là một chuỗi định dạng.
Tôi sẽ cung cấp cho bạn một chuỗi định dạng ngay bây giờ.
Tôi nghĩ rằng chúng ta phải nói, 127s \ n, rất nhiều đó là không cần thiết.
Ý tưởng về những gì mà chuỗi định dạng, bạn có thể nghĩ quét f như là trái ngược của f in.
Vì vậy, in f, f in chúng tôi cũng sử dụng loại của tham số định dạng,
nhưng trong f in những gì chúng tôi đang làm là hãy nhìn vào tương đương.
Vì vậy, in f, và có thực sự là f in f, tham số đầu tiên là có được f.
Khi bạn in f, chúng tôi có thể nói một cái gì đó như "in 127s \ n" và sau đó nếu chúng ta vượt qua nó một số chuỗi,
nó sẽ in chuỗi này và sau đó là một dòng mới.
127 phương tiện, tôi khá chắc chắn, nhưng tôi đã không bao giờ giới hạn bản thân mình để nó,
Bạn thậm chí không cần phải nói '127 'trong f in,
nhưng những gì nó có nghĩa là in 127 ký tự đầu tiên.
Vì vậy, tôi khá chắc chắn đó là trường hợp. Bạn có thể Google cho điều đó.
Tuy nhiên, trong một trong những tiếp theo tôi gần như tích cực nó có nghĩa là.
Vì vậy, đây là in 127 ký tự đầu tiên, tiếp theo là một dòng mới.
F quét f bây giờ, thay vì nhìn vào một biến và in ấn,
nó sẽ nhìn vào một số chuỗi, và lưu trữ các mẫu vào biến.
Hãy để thực sự sử dụng f quét trong một ví dụ khác.
Vì vậy, hãy nói rằng chúng tôi đã có một số int x = 4,
và chúng tôi muốn tạo ra một chuỗi làm bằng - muốn tạo ra các chuỗi
đó là như thế, điều này sẽ đến muộn hơn nhiều,
một cái gì đó giống như 4.jpg.
Vì vậy, đây có thể là một chương trình, nơi bạn sẽ có truy cập tổng hợp,
tổng hợp chống lại tôi, và bạn muốn lưu một loạt các hình ảnh.
Vì vậy, bạn muốn lưu i.jpg, nơi mà tôi có một số lần lặp của vòng lặp của bạn.
Vì vậy, làm thế nào để chúng ta làm cho chuỗi này cho rằng JPEG?
Nếu bạn muốn in 4.jpg, chúng tôi chỉ có thể nói f in, d.jpg%,
và sau đó nó sẽ in cho rằng JPEG.
Nhưng nếu chúng ta muốn lưu 4.jpg chuỗi, chúng tôi sử dụng f quét.
Vì vậy, string s - thực sự chúng tôi không thể nào nhân vật, char s, chúng ta hãy đi 100.
Vì vậy, tôi chỉ tuyên bố một số mảng của 100 ký tự,
và đó là những gì chúng ta chắc chắn sẽ được lưu trữ đó JPEG.
Vì vậy, chúng ta sẽ sử dụng quét f, và định dạng, làm thế nào chúng tôi sẽ nói d.jpg%
để in 4.jpg, định dạng này sẽ được% d.jpg.
Vì vậy, định dạng là% d.jpg, những gì chúng ta muốn thay thế d% với x,
và bây giờ chúng ta cần phải lưu trữ chuỗi một nơi nào đó.
Và nơi chúng tôi đang đi để lưu trữ chuỗi này là trong mảng.
Vì vậy, sau khi dòng này của mã, s, nếu chúng ta in f% s, biến s,
nó sẽ in 4.jpg.
Vì vậy, f quét f là giống như quét f, ngoại trừ bây giờ nó đang tìm kiếm trên tập tin này
cho những gì để lưu trữ trong s.
Đó là những gì đối số cuối cùng là có được.
Chúng tôi muốn để lưu trữ - "Gia đình f Scan quét chức năng trong cả hai theo định dạng như thử dưới đây.
Nếu bất kỳ được lưu trữ trong các điểm vị trí, bạn có thể quay trở lại - "
Không, chúng tôi có thể là tốt. Hãy để tôi suy nghĩ cho một thứ hai.
Vì vậy, quét f không - những gì heck là chức năng nào đó?
Vì vậy, quét f không phải là đi để có một số nguyên và làm dot jpg.
Nó sẽ [lầm bầm].
Lưu biến int trong chuỗi int C.
Biến này là gì, hoặc chức năng này gọi là gì?
Vâng. Đó có. Vì vậy, những gì tôi đã xác định cho bạn trước khi được in f s,
- có ý nghĩa nhiều hơn nữa, lý do tại sao tôi nói rằng nó đã được nhiều hơn như f in.
Scan f vẫn là loại như in f, nhưng s in f để quét nó
và thay thế các biến và lưu trữ nó trong một chuỗi.
Thay vì in ấn nó, nó lưu nó trong một chuỗi.
Vì vậy, bỏ qua điều đó hoàn toàn. Bạn vẫn có thể nghĩ đến sự xác định định dạng như của f in.
Vì vậy, bây giờ, nếu chúng ta muốn làm điều 4.jpg, chúng tôi sẽ làm in s f, x này.
Vì vậy, những gì quét f được làm những gì đã được câu hỏi của bạn sẽ được?
[Sinh viên] Tôi chỉ nhầm lẫn về những gì chúng tôi đang cố gắng làm ngay tại đây
với JPEG. Bạn có thể giải thích thêm 1 thời gian?
Vì vậy, đây là nó ít có liên quan đến f quét f bây giờ, hy vọng, nó sẽ buộc trở lại trong một số loại cách.
Nhưng những gì tôi bước đầu đã có ý định để hiển thị - điều này thực sự liên quan trực tiếp đến [những? F5]
Bạn sẽ được sử dụng f in s, ở đâu, nói rằng chúng ta có 100 hình ảnh,
và bạn muốn đọc 1.jpg image, 2.jpg, 3.jpg.
Vì vậy, để làm được điều đó, bạn cần đến f mở, và sau đó bạn phải vượt qua trong chuỗi mà bạn muốn mở.
Vì vậy, chúng tôi muốn mở 1.jpg, để tạo ra các chuỗi đó là 1.jpg,
f in chúng tôi làm s của% d.jpg chúng ta không làm cho int i = 0.
i <40, i + +.
Vì vậy, f in% s d.jpg của i.
Vì vậy, sau khi đường dây này, bây giờ biến hoặc mảng sẽ 1.jpg.
Hoặc, 0.jpg, 1.jpg, 2.jpg. Và vì vậy chúng tôi có thể mở, lần lượt, mỗi hình ảnh để đọc.
Vì vậy, đó là những gì s in f không. Bạn có thấy những gì s in f hiện đang làm?
[Sinh viên] Được rồi, do đó, nó dùng - nó tạo ra một chuỗi, something.jpg, và sau đó lưu nó.
Vâng. Nó tạo ra - đây là một chuỗi định dạng, giống như quét f và f in,
nơi nó chèn tất cả các biến vào đối số thứ hai, có thể là như trái ngược với tôi.
Có lẽ - Ý tôi là, đó là trường hợp. Nhưng bất cứ điều gì, thứ tự của các đối số.
Nó sẽ để chèn tất cả các biến vào chuỗi định dạng
và sau đó lưu trữ vào bộ đệm của chúng tôi, chúng tôi gọi đó là một bộ đệm, nó là nơi chúng tôi đang lưu trữ các chuỗi.
Vì vậy, chúng tôi đang lưu trữ bên trong của chuỗi định dạng một cách chính xác,% d đã được thay thế bằng 4.
[Sinh viên] Vì vậy, nếu chúng ta làm điều này, là biến f sẽ được bố trí?
Vâng. Vì vậy, chúng ta nên đóng f ban đầu trước khi làm điều này.
Nhưng - và sau đó cũng có thể, nếu không có một e mở ra, sau đó chúng tôi sẽ cần phải nói -
Yeah. Nhưng nó sẽ mở ra một trăm tập tin khác nhau.
[Sinh viên] Nhưng chúng ta sẽ không có thể truy cập hoặc - okay.
Okay. Vì vậy, quét f, f quét f, là loại cùng một ý tưởng,
nhưng thay vì, thay vì lưu trữ nó vào một chuỗi, nó giống như bạn bây giờ
đi qua một sting và mô hình phù hợp với chuỗi đó và lưu trữ các kết quả vào các biến.
Bạn có thể sử dụng e quét để phân tích trên một cái gì đó giống như 4.jpg, và lưu trữ trong 4 số nguyên vào x int tổng hợp.
Đó là những gì chúng ta có thể sử dụng e quét.
F quét f sẽ làm điều đó tại dòng lệnh.
Tôi thực sự đẹp, chắc chắn đây là những gì thư viện CS50 không.
Vì vậy, khi bạn nói, "có được int", đó là quét e-ing qua - quét f là cách bạn có được người dùng nhập vào.
F quét e là sẽ làm điều tương tự nhưng bằng cách sử dụng một tập tin để quét qua.
Vì vậy, ở đây, chúng ta đang quét qua tập tin này.
Mẫu, chúng tôi đang cố gắng để phù hợp với một số chuỗi dài là 127 ký tự
tiếp theo là một dòng mới
Vì vậy, tôi khá chắc chắn rằng chúng tôi thậm chí chỉ có thể nói "phù hợp với s," từ trong từ điển
chúng tôi xảy ra để có, chúng tôi sẽ được bảo đảm từ không lâu,
và cũng có thể f f quét, tôi nghĩ, sẽ dừng lại ở các dòng mới không có vấn đề gì.
Nhưng chúng tôi sẽ bao gồm các dòng mới trong trận đấu, và -
[Sinh viên] Nếu chúng ta không bao gồm các dòng mới, sẽ không tìm thấy các bộ phận của một từ?
- Mỗi - nhìn từ điển -
Vì vậy, trong từ điển, đó là tất cả các từ của chúng tôi.
Mỗi một là trên một dòng mới.
F quét được sẽ chọn từ này.
Nếu chúng ta không bao gồm các dòng mới, sau đó nó có thể là f quét tiếp theo sẽ chỉ đọc những dòng mới.
Tuy nhiên, bao gồm cả dòng mới sau đó chỉ cần bỏ qua dòng mới.
Nhưng chúng ta sẽ không bao giờ có được một phần của một từ, vì chúng ta đang luôn luôn đọc một dòng mới, không có vấn đề gì.
[Sinh viên] Nhưng nếu bạn tìm kiếm từ "cissa" như cissa.
Nó sẽ tìm thấy điều đó, và nói rằng đó là một trận đấu?
Vì vậy, ở đây chúng tôi - nó sẽ đọc trong - điều này thực sự là một điểm tốt.
Chúng tôi sẽ không bao giờ sử dụng hiện nay - từ chúng tôi đang tìm kiếm các đối số dòng lệnh đầu tiên.
Vì vậy, chuỗi, từ = argv 1.
Vì vậy, các chuỗi chúng tôi đang tìm kiếm là argv 1.
Chúng tôi không tìm kiếm một từ ở tất cả các trong f quét của chúng tôi.
Những gì chúng tôi đã làm với quét f là nhận được mỗi từ trong từ điển,
và sau đó khi chúng tôi có từ đó chúng ta sẽ sử dụng strcmp để so sánh chúng.
Chúng ta sẽ so sánh các từ ngữ của chúng tôi và những gì chúng ta vừa đọc.
Vì vậy, chắc chắn, chúng ta sẽ kết thúc làm một bó quét fs
cho đến khi nó chỉ như vậy sẽ xảy ra mà quét f sẽ trở lại -
nó sẽ trở lại một, miễn là nó đã xuất hiện một từ mới,
và nó sẽ trở lại một cái gì đó khác ngay sau khi nó đã không thành công để phù hợp với từ.
Chúng tôi đọc qua toàn bộ từ điển, lưu trữ từng dòng từng chữ vào biến s.
Sau đó, chúng tôi đang so sánh từ với s, và nếu so sánh == 0,
strcmp xảy ra để mang lại 0 nếu kết hợp đã được thực hiện.
Vì vậy, nếu nó là 0, sau đó chúng tôi có thể in f, lần xuất hiện,
hoặc một từ trong từ điển, hoặc bất cứ điều gì bạn muốn in f.
Và sau đó chúng tôi không muốn để f gần hơn và hơn nữa.
Đây là loại điều chúng tôi muốn làm, và chúng tôi không chỉ tìm kiếm từ trong từ điển.
Vì vậy, chúng ta có thể làm điều đó, nếu chúng ta muốn tìm kiếm mô hình của họ, cissa, như bạn đã nói trước,
nếu chúng ta muốn tìm kiếm mô hình mà, sau đó nó sẽ thất bại trong trường hợp
bởi vì đó không phải là thực sự là một từ, nhưng một trong những từ trong từ điển xảy ra để có trong nó.
Vì vậy, nó sẽ phù hợp với từ này, nhưng tập hợp con của từ này không phải là một từ chính nó.
Nhưng đó không phải là làm thế nào chúng ta đang sử dụng nó, chúng tôi đang đọc trong mỗi từ
và sau đó so sánh từ chúng tôi có với từ đó.
Vì vậy, chúng tôi luôn so sánh từ đầy đủ.
Tôi có thể gửi ra các giải pháp hoàn thiện sau đó.
Đây là loại của câu trả lời gần đúng, tôi nghĩ.
[Sinh viên bình luận, không thể hiểu]
Ồ, tôi nhận được thoát khỏi đó trước khi? Char s, tôi đoán chúng tôi đã nói 127 - Tôi quên đi những gì lớn nhất là.
Chúng tôi sẽ chỉ làm 128; vì vậy bây giờ s là đủ dài.
Chúng ta không cần in bất cứ điều gì.
Chúng tôi cũng muốn có để đóng tập tin của chúng tôi, và đó nên được về câu trả lời đúng.
CS50.TV