C # 1 đầu tiên (phải sang trái) trong số nhị phân


10

Tôi đang cố gắng sử dụng C # để tìm chỉ số của 1 đầu tiên (phải sang trái) trong biểu diễn nhị phân của một số. Ví dụ: vì 100 trong nhị phân là:

0b1100100

1 đầu tiên ở vị trí thứ ba từ bên phải, vì vậy nó sẽ mang lại 3.

234 nên mang lại 2, 0 nên mang lại 0, v.v.

Đây là giải pháp hiện tại của tôi:

k < 1 ? 0 :(int)Math.Log(k & -k, 2) + 1;

Bất kỳ cách nào tôi có thể làm điều này ngắn hơn?


1
Mẹo rõ ràng là loại bỏ khoảng trắng bên ngoài của bạn. Tôi thấy 10 khoảng trống mà bạn có thể dễ dàng loại bỏ.
James

Convert.ToString(k,2).IndexOf("1")là những gì bạn muốn, hoặc một cái gì đó tương tự, trang web sai mặc dù.
Bạch tuộc ma thuật Urn

14
@ cử tri thân thiết - Tại sao lại bỏ phiếu kín? Tôi nghĩ rằng đây là một câu hỏi mẹo về chủ đề . Hoặc có bất kỳ thay đổi quy tắc nào tôi đã bỏ lỡ trong vấn đề này?
Chấn thương kỹ thuật số

Câu trả lời:


3

Nếu chỉ có nội tại dành riêng cho máy cụ thể C # thì có một lệnh duy nhất có thể thực hiện điều này bằng ngôn ngữ lắp ráp x86 và trên hầu hết các kiến ​​trúc bộ xử lý khác. Sau đó, bạn không chỉ có mã ngắn nhất, mà rất có thể là nhanh nhất.

Trong thực tế, làm cho mã này ngắn hơn là một vấn đề cực kỳ nhàm chán so với làm cho mã này nhanh . Có tất cả các loại giải pháp thực sự gọn gàng, hiệu quả, đôi chút, và bạn cũng có thể xem xét sử dụng bảng tra cứu.

Không ai trong số đó quan trọng cho việc chơi golf, mặc dù. Đối với tôi có vẻ như giải pháp hiện tại của bạn là tốt nhất bạn có thể làm. Tất nhiên, bạn có thể xóa khoảng trắng thừa:

k<1?0:(int)Math.Log(k&-k,2)+1

Cá nhân tôi sẽ viết nó như sau:

k>0?(int)Math.Log(k&-k,2)+1:0

bởi vì tôi nghĩ rằng sẽ rõ ràng hơn một chút khi có hướng của bài kiểm tra có điều kiện theo cách đó, cũng như so sánh nó với số không, nhưng tôi đoán đó là sáu cách một, nửa tá cách khác.

C # không hỗ trợ chuyển đổi ngầm từ intđến boolnhư C và C ++ làm, vì vậy bạn có thể không thực sự rút ngắn thử nghiệm có điều kiện thêm nữa.

Bạn cũng bị mắc kẹt với các diễn viên rõ ràng từ double(như đã trả lại của tôi Math.Log) đến int, vì C # sẽ không cho phép điều này xảy ra ngầm. Tất nhiên, đó thường là một điều tốt bởi vì nó sẽ chỉ ra rằng bạn có một vấn đề hiệu suất lớn ở đây: quảng bá intcho một double, tính toán nhật ký của a double, và sau đó chuyển đổi doublekết quả trở lại intsẽ chậm một cách ồ ạt , vì vậy, đó thường là một điều gì đó mà bạn muốn tránh. Nhưng đây là những loại sai lầm bạn phải đưa ra khi chơi golf mã.


Ban đầu tôi nghĩ ra

k > 0
      ? ((k & -k) >> 1) + 1
      : 0

(tất nhiên là không rõ ràng), điều này tránh việc lấy logarit và do đó là một sự cải thiện về kích thước và tốc độ mã. Thật không may, điều này không phải lúc nào cũng nhận được câu trả lời đúng và tôi cho rằng đó là một yêu cầu không linh hoạt. :-) Cụ thể, nó không thành công nếu giá trị đầu vào ( k) là hệ số 8. Điều này có thể sửa được, nhưng không phải là không làm cho mã dài hơn Math.Logphiên bản.


Lưu ý rằng đối với môn đánh gôn, mã Mathphải có đủ điều kiện để phiên bản khác của bạn tốt hơn mặc dù tôi thực sự chưa đếm được byte.
TheLethalCoder

Bạn có nghĩa là một trong những sản xuất đầu ra sai? @the
Cody Grey

Vâng, bạn nói có một sửa chữa cho nó nhưng nó sẽ làm cho nó dài hơn. Nếu sửa chữa ngắn hơn so với khi phiên bản OP bao gồm System.thì nó phải ngắn hơn và chính xác.
TheLethalCoder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.