C # แรก 1 (ขวาไปซ้าย) ในเลขฐานสอง


10

ฉันพยายามใช้ C # เพื่อค้นหาดัชนีของ 1 (ขวาไปซ้าย) ในการแทนเลขฐานสองของตัวเลข ตัวอย่างเช่นตั้งแต่ 100 ในไบนารีคือ:

0b1100100

1 แรกอยู่ในตำแหน่งที่สามจากด้านขวาดังนั้นควรให้ 3

234 ควรให้ผล 2, 0 ควรได้ 0, เป็นต้น

นี่คือทางออกปัจจุบันของฉัน:

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

ฉันจะทำให้มันสั้นกว่านี้ได้ไหม?


1
เคล็ดลับที่ชัดเจนคือการลบช่องว่างที่ไม่เกี่ยวข้องออกไป ฉันเห็น 10 ช่องว่างที่คุณสามารถลบออกได้อย่างง่ายดาย
James

Convert.ToString(k,2).IndexOf("1")เป็นสิ่งที่คุณต้องการหรือสิ่งที่คล้ายกันไซต์ผิด
Magic Octopus Urn

14
@ close-voters - ทำไมต้องโหวตปิด ฉันคิดว่านี่เป็นคำถามเคล็ดลับในหัวข้อ หรือมีการเปลี่ยนแปลงกฎใด ๆ ที่ฉันพลาดไปในเรื่องนี้?
Digital Trauma

คำตอบ:


3

ถ้าเฉพาะ C # ที่รองรับเฉพาะเครื่องภายใน ... มีคำสั่งเดียวที่สามารถทำได้ในภาษาแอสเซมบลี x86 และสถาปัตยกรรมตัวประมวลผลอื่น ๆ ส่วนใหญ่เช่นกัน จากนั้นคุณจะไม่เพียง แต่มีรหัสย่อที่สุดเท่านั้น

ความจริงแล้วการทำให้โค้ดนี้สั้นลงเป็นปัญหาที่น่าเบื่ออย่างยิ่งเมื่อเปรียบเทียบกับการทำให้โค้ดนี้เร็วขึ้น มีทุกประเภทของโซลูชั่นที่ประณีตมีประสิทธิภาพและมีประสิทธิภาพมากและคุณสามารถลองใช้ตารางค้นหา

ไม่มีสิ่งใดที่มีความสำคัญต่อการเล่นกอล์ฟ ดูเหมือนว่าฉันจะแก้ปัญหาในปัจจุบันของคุณเป็นสิ่งที่ดีที่สุดที่คุณสามารถทำได้ แน่นอนคุณสามารถลบช่องว่างที่ไม่จำเป็นออกได้:

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

ส่วนตัวฉันจะเขียนมันเป็น:

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

เพราะฉันคิดว่ามันชัดเจนกว่าเล็กน้อยที่จะมีทิศทางของการทดสอบตามเงื่อนไขเช่นเดียวกับการเปรียบเทียบกับศูนย์ แต่ฉันคิดว่ามันเป็นหกทางเดียวครึ่งอีกครึ่งโหล

C # ไม่รองรับการแปลงโดยนัยจากintเป็นboolชอบ C และ C ++ ทำดังนั้นคุณจึงไม่สามารถย่อการทดสอบตามเงื่อนไขอีกต่อไปได้

คุณยังติดอยู่กับการส่งที่ชัดเจนจากdouble(ตามที่ส่งคืนของฉันMath.Log) ถึงintเนื่องจาก C # จะไม่อนุญาตให้สิ่งนี้เกิดขึ้นโดยปริยาย แน่นอนว่าปกติเป็นสิ่งที่ดีเพราะมันจะชี้ให้เห็นว่าคุณมีขนาดใหญ่ปัญหาประสิทธิภาพการทำงานที่นี่: การส่งเสริมintไปdoubleคำนวณบันทึกที่doubleแล้วแปลงdoubleผลกลับไปที่intจะได้รับอย่างหนาแน่นช้าดังนั้นจึงเป็นเรื่องปกติบางสิ่งบางอย่าง ที่คุณต้องการหลีกเลี่ยง แต่นี่คือความวิปริตที่คุณต้องทนเมื่อเล่นกอล์ฟ


ตอนแรกฉันคิด

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

(แน่นอนว่าไม่ดีสำหรับความชัดเจน) ซึ่งหลีกเลี่ยงการใช้ลอการิทึมดังนั้นจึงเป็นการปรับปรุงขนาดและความเร็วของโค้ด น่าเสียดายที่นี่ไม่ได้คำตอบที่ถูกต้องเสมอไปและฉันคิดว่านั่นเป็นข้อกำหนดที่ไม่ยืดหยุ่น :-) โดยเฉพาะมันล้มเหลวถ้าค่าอินพุต ( k) เป็นปัจจัย 8 นี่เป็นสิ่งที่แก้ไขได้ แต่ไม่ใช่โดยไม่ทำให้โค้ดยาวกว่าMath.Logเวอร์ชัน


โปรดทราบว่าสำหรับการเขียนโค้ดMathจะต้องมีคุณสมบัติครบถ้วนดังนั้นรุ่นอื่น ๆ ของคุณควรจะดีกว่าแม้ว่าฉันจะไม่ได้นับจำนวนไบต์ที่แท้จริง
TheLethalCoder

คุณหมายถึงอันที่สร้างผลลัพธ์ผิดหรือเปล่า? @the
Cody Gray

คุณบอกว่ามีการแก้ไข แต่มันจะทำให้มันอีกต่อไป หากการแก้ไขสั้นกว่าเมื่อรวมรุ่น OP System.แล้วการแก้ไขควรสั้นลงและถูกต้อง
TheLethalCoder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.