Điều thú vị mà khi giải 1 đề đơn giản mình rút ra được!

Đề : tạo hàm so sánh số nào lớn nhất trong 2 số?
code 1:

#include <stdio.h>

int so_lon_nhat(int so_1,int so_2);
int main()
{
    printf("so lon nhat trong 2 so la: %d",so_lon_nhat(7,89));
    return 0;
}

int so_lon_nhat(int so_1,int so_2)
{
    int so_sanh1,so_sanh2,ketqua;
    so_sanh1=so_1-so_2;
    so_sanh2=so_2-so_1;
    if (so_sanh1>so_sanh2)
        ketqua=so_1;
    else
        ketqua=so_2;
    return ketqua;
}

và code 2

#include <stdio.h>
#include <stdlib.h>
int so_lon_nhat(int so_1,int so_2);
int main()
{
    printf("so lon nhat trong 2 so la: %d",so_lon_nhat(7,89));
    return 0;
}

int so_lon_nhat(int so_1,int so_2)
{
    int ketqua;
    if(so_1>so_2)
        ketqua=so_1;
    else
        ketqua=so_2;
  
    return ketqua;
}

Quá trình của mình là đọc đề! mình phân tích đề : yêu cầu phép so sánh ( ở đây là so sánh lớn hơn ) giá trị so sánh là 1 số ( ở đây mình cho là 1 số nguyên ). mình nhớ lại hồi tiểu học cô giáo nói quả táo nào to hơn nghĩa là có trọng lượng khi cân nặng hơn. áp dụng vào 2 con số mình nghĩ so sánh lấy 2 số đem gọt đi đến khi 2 số bằng nhau thì ta đem cân phần đã gọt phần nào nặng hơn thì số đó nặng hơn. thế là mình lấy 2 số trừ cho nhau ( lấy mỗi số là 1 thước đo trung bình ) sau đó lấy kết quả đã trừ đem so sánh với nhau và kết luận cho code 1. sau đó trong đầu mình lại loé lên cái bóng đèn là mình vừa đem 2 phần gọt so sánh với nhau thế tại sao mình không so sánh thẳng 2 số và mình làm lại với code thứ 2! mình rút ra được 1 bài học đó là có những thứ mình nghĩ nó phải cao siêu lắm nhưng thật thì nó rất đơn giản và 1 ý nữa là sẽ học được nhiều hơn từ việc coi là ngu ngốc này!

5 Likes

Mình thì hay nghĩ: input là gi, output cần gì. Sau đó mới là thuật toán :wink:

4 Likes

e chưa có xíu knh nghiệm lập trình j cả! học xong lớp 12 từ năm 2008 rồi đi làm đến nay mới có cơ hội để học! toàn mò mẫm từ video clip của a Đạt up! chứ mù ! máy tính tự sửa! nói chung là ko có thầy hay trường lớp j cả!

3 Likes

Cũng bài toán tìm số lớn nhất trong 2 số (nhưng giải bằng thao tác trên bit, post ké tham khảo cho vui thôi :D)

#include <iostream>
using namespace std;

int main() {
	
	int number1, number2;
        cin >> number1 >> number2;
	
	int max =  number2 ^ ((-(number1 > number2)) & (number1 ^ number2));
	
	cout << max;
	
	return 0;
}
3 Likes

Bài này dựa trên tính chất của phép Xor. Tính chất đó như sau (do mình tự rút ra thôi):

Có 2 số a và b, a xor b sẽ ra một số mà mình gọi đó là số trung gian tg.
a xor tg = b;
b xor tg = a;

:smiley:

Thêm 1 tính chất vui của bit nữa mà mình nhận thấy:

2 số a và b thì ta có:

a + b = number;
(a and b) + (a or b) = number;

:smiley:

2 Likes

mấy bài toán hại não với nhiều toán tử ko rõ ràng nếu như k cần thiết thì đừng nên tốn time. @ltd a nói như vậy! Bài này thì cứ ưu tiên trong ngoặc à a? (-(number1 > number2)) cái này là 1 số âm nếu number dương và là dương nếu number âm phải ko anh? @Is2IT

đại ka ơi! xor là j vậy?

Như mình nói theo tính chất phép xor trên thì:

(number1 ^ number2) = số trung gian tg.

khoan để ý cái (- (number1 > number2)) đã, xét lại tính chất phép xor mình nói ở trên,
ta sẽ có number2 ^ (number1 ^ number2) <=> number2 ^ tg;

bây giờ mình sẽ phải quyết định:

  • Nếu number2 là max, number2 xor tg sẽ thành number1 lại rồi, như thế thì không đc thực hiện phép xor.
  • Nếu number1 là max, phải thực hiện number2 xor tg để thành number1.

vậy cái biểu thức (- (number1 > number2)) sẽ quyết định.

Nếu number1 > number2 đúng sẽ trả về 1, - (number1 > number2) sẽ thành -1.
-1 biễu diễn trong nhị phân là 32 bit 1 (11111111111111111111111111111111)
Theo tính chất phép and thì chỉ có bit 1 and với bit 1 thì mới giữ nguyên 1, còn lại thì thành bit 0.
Nghĩa là số trung gian lúc này sẽ được giữ nguyên, vì and với -1 (toàn bit 1 mà).
Vậy thì lúc này number2 sẽ được xor với tg để trở thành number1 (number1 > number2)

Trường hợp ngược lại là khi number2 > number1, nghĩa là biểu thức - (number1 > number) trả về giá trị 0.
lúc này số trung gian and với 0 thì thành 0.
number2 xor với 0 thì thành lại chính nó.

Giải thích như vầy cũng ko biết đã rõ chưa nữa :smiley: nhưng mình chỉ hiểu ngang đó thôi

Vậy thì phải đề nghị a Đạt làm một vài bài về các phép toán về bit trong C/C++ thôi :smiley:

1 Like

Trong C/C++ họ định nghĩa những phép toán thao tác trên bit theo những nghĩa khác nhau, bao gồm những phép như: and ( & ), or ( | ), xor ( ^ ), not ( ~ ), …

Trong đó phép xor nghĩa là để kiểm tra xem 2 bit đc so sánh có khác nhau hay không.
1 xor 1 = 0
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 0

Cho anh góp ý cái này không liên quan đến nội dung bài post đâu. Nhưng để sử dụng diễn đàn hiệu quả hơn ta nên post 1 post cho 2 bài gần kề nhau. Ví dụ như 2 bài này cùng trả lời cho 1 câu hỏi

Để trả lời cho câu hỏi này thì @minh_vu_03 có thể tạo 1 post thôi :smile:

1 Like

dạ em cũng muốn post cùng 1 lúc, nhưng khổ cái lúc đó không nghĩ ra được để viết. Post xong rồi nó mới nhớ a Đạt ơi :frowning:

lại dốt tiếng anh rôi! giờ mới bik ^ là xor. ọc máu thật! mới đầu cứ nghĩ nó là 1 khái niệm gì chưa nghe bao giờ! tks

@minh_vu_03 em có thể edit bài của mình được đấy

2 Likes

Nhiều khi thao tác với bit cũng có cái hay với nó, chỉ là trình độ mình thấp kém (không phải dạng thánh bit) nên không nhìn ra được ứng dụng của nó thôi.
https://graphics.stanford.edu/~seander/bithacks.html

Link trên là sưu tập những thao tác tính toán trên bit, một số cái mình hiểu, số còn lại mình cũng không thể hiểu nổi.

Thỉnh thoảng cũng có mấy ứng dụng đơn giản như:

  • Kiểm tra 1 số là số chẵn hay lẻ:
#include <iostream>
using namespace std;

bool is_odd(int number)		{
	
	return number&1;
}

int main() {
	
	cout << (is_odd(13)? "Odd number" : "Even number");
	return 0;
}
  • Hay là tìm min hoặc max trong 2 số mà mình nói ở trên.
  • Hoặc mình muốn lưu giữ trạng thái của một mảng có số lượng phần tử bé ( chẳng hạn < 32 phần tử ) để xem có bao nhiêu số lẻ:
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;

#define max 31

bool is_odd(int number)		{
	
	return number&1;
}

int main() {
	
	int arr[max];
	int state = 0;
	
	srand(time(NULL));
	for(int i = 0; i < max; i++)	{
		
		arr[i] = rand()%100;
		cout << arr[i] << " ";
		
		state += is_odd(arr[i]);
		cout << (state&1) << endl;
		
		state <<= 1;
	}
	
	int temp = 0;
	for(int i = 0; i <= max; i++,state >>= 1)	{
		
		if(state&1)
			temp++;
	}
	
	cout << endl << temp;
	return 0;
}

Mấy cái trên mình tự nghĩ ra cho vui thôi, chứ thao tác với bit ứng dụng nhiều thứ lắm.

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