เครื่องถอดรหัสรหัสมอร์สในภาษา Perl

ฉันกำลังพยายามสอนตัวเองด้วยภาษา Perl และฉันก็ประสบปัญหา... เมื่อคืนฉันทำโปรแกรมคำนวณค่าเฉลี่ยของชุดตัวเลขที่ผู้ใช้ระบุเพื่อเรียนรู้เกี่ยวกับรายการและการป้อนข้อมูลของผู้ใช้ ดังนั้นวันนี้ฉันคิดว่าฉันจะทำ เครื่องถอดรหัสรหัสมอร์สเพื่อเรียนรู้เกี่ยวกับแฮช ฉันได้ดูหนังสือที่ฉันซื้อแล้ว แต่มันไม่ได้อธิบายแฮชได้ดีมาก... จริงๆ แล้วมันไม่ได้อธิบายสิ่งต่าง ๆ มากมายได้ดีมาก ความช่วยเหลือใด ๆ ที่จะได้รับการชื่นชม!

ยังไงก็ตาม ผมอยากเขียนโปรแกรมถอดรหัสรหัสมอร์สที่ผู้ใช้ป้อนเข้าไป ดังนั้นผู้ใช้จะป้อน:

-.-.
.-
-
...
!
.-.
..-
.-..
.

เครื่องหมายอัศเจรีย์จะหมายถึงคำที่แยกจากกัน ข้อความนี้จะส่งคืน "กฎของแมว" ให้กับผู้ใช้ ด้านล่างนี้คือโค้ดที่ผมมีจนถึงตอนนี้... จำไว้ครับ.. ผมเขียนโปรแกรมด้วยภาษา Perl ไม่ถึง 24 ชั่วโมง 555

รหัส:

  use 5.010;




my %morsecode=(
    '.-'    =>'A',  '-...'  =>'B',  '-.-.'  =>'C',  '-..'   =>'D',
    '.' =>'E',  '..-.'  =>'F',  '--.'   =>'G',  '....'  =>'H',
    '..'    =>'I',  '.---'  =>'J',  '-.-'   =>'K',  '.-..'  =>'L',
    '--'    =>'M',  '-.'    =>'N',  '---'   =>'O',  '.--.'  =>'P',
    '--.-'  =>'Q',  '.-.'   =>'R',  '...'   =>'S',  '-' =>'T',
    '..-'   =>'U',  '...-'  =>'V',  '.--'   =>'W',  '-..-'  =>'X',
    '-.--'  =>'Y',  '--..'  =>'Z',  '.----' =>'1',  '..---' =>'2',
    '...--' =>'3',  '....-' =>'4',  '.....' =>'5',  '-....' =>'6',
    '--...' =>'7',  '---..' =>'8',  '----.' =>'9',  '-----' =>'0',
    '.-.-.-'=>'.',  '--..--'=>',',  '---...'=>':',  '..--..'=>'?',
    '.----.'=>'\'', '-...-' =>'-',  '-..-.' =>'/',  '.-..-.'=>'\"'
);

my @k = keys %morsecode;
my @v = values %morsecode;

say "Enter a message in morse code separated by a line. Use the exclamation point (!) to separate words. Hit Control+D to signal the end of input.";
my @message = <STDIN>;
chomp @message;

my $decodedMessage = encode(@message);


sub encode {
    foreach @_ {
    if (@_ == @k) {
        return @k;

#This is where I am confused... I am going to have to add the values to an array, but I don't really know how to go about it.


        }
    else if(@_ == '!') {return ' '}
    else
    {
    return 'Input is not valid';
    }
    }
}

person JLott    schedule 25.01.2013    source แหล่งที่มา
comment
ฉันขอแนะนำให้ดู tizag.com/perlT/perlarrays.php และ tizag.com/perlT/perlhashes.php หรือบทช่วยสอนอาร์เรย์/แฮชอื่น ๆ ที่คุณพบใน Google สำหรับเรื่องนั้น ขอให้โชคดี.   -  person dutt    schedule 26.01.2013
comment
ขอบคุณ! ฉันรู้สึกทราบซึ้ง!   -  person JLott    schedule 26.01.2013
comment
จุดเริ่มต้นที่ดี: เรียนรู้เว็บไซต์ Perl, หนังสือ Perl สมัยใหม่, หนังสือการเรียนรู้ Perl สิ่งนี้ น่าจะช่วยเรื่องแฮชได้   -  person Craig Treptow    schedule 26.01.2013
comment
นอกจากนี้ แนะนำให้ใส่ use warnings; และ use strict; ลงในโค้ดทั้งหมดของคุณเพื่อช่วยตรวจจับข้อผิดพลาด   -  person Craig Treptow    schedule 26.01.2013
comment
ก่อนที่คุณจะดำเนินการใดๆ ให้วาง use strict; และ use warnings; ไว้ที่ด้านบนสุดของสคริปต์ พวกเขาช่วยได้ แม้ว่าคุณอาจจะไม่ชอบพวกเขาในตอนแรกก็ตาม ตัวเลือกที่เหมาะสมของโปรเจ็กต์ที่ 1 สำหรับการเรียนรู้เกี่ยวกับแฮช   -  person William    schedule 26.01.2013
comment
@k และ @v ไม่มีจุดหมาย นอกจากนี้ย่อยของคุณควรเรียกว่า decode ไม่ใช่ encode   -  person Brad Gilbert    schedule 26.01.2013
comment
ขอขอบคุณทุกท่านสำหรับความช่วยเหลือของคุณ! สิ่งนี้ช่วยได้มากในการเรียนรู้พื้นฐานที่มีประโยชน์มากมาย   -  person JLott    schedule 26.01.2013


คำตอบ (3)


รหัสของคุณมีข้อผิดพลาดทางวากยสัมพันธ์สองประการ: foreach ต้องมี รายการ เพื่อวนซ้ำ; นี่หมายถึงวงเล็บ ต่างจากภาษา C และภาษาอื่นๆ Perl ไม่รองรับ else if (...) ให้ใช้ elsif (...) แทน

มีข้อผิดพลาดทางความหมายบางประการ: ค่าปัจจุบันของการวนซ้ำจะถูกเก็บไว้ใน $_ อาร์เรย์ @_ มีอาร์กิวเมนต์ของการเรียกใช้ฟังก์ชันของคุณ

Perl เปรียบเทียบสตริงและตัวเลขแตกต่างกัน:

Strings Numbers
eq      ==
lt      <
gt      >
le      <=
ge      >=
ne      !=
cmp     <=>

ใช้ตัวดำเนินการที่ถูกต้องสำหรับงานที่มีอยู่ ในกรณีนี้คือตัวดำเนินการแบบสตริง

(โค้ดของคุณ @_ == @k ทำอะไรบางอย่าง กล่าวคือ การใช้อาร์เรย์ใน บริบท ที่เป็นตัวเลข ซึ่งทำให้เกิดจำนวนองค์ประกอบ ซึ่งจะถูกเปรียบเทียบในภายหลัง @_ == '!' นั้นแปลกมาก)


สิ่งที่คุณต้องการทำคือแมปค่าที่ป้อนเข้ากับรายการอักขระ แฮชของคุณกำหนดการแมปนี้ แต่เราต้องการใช้มัน Perl มีฟังก์ชัน map ซึ่งใช้งานได้เหมือนกัน

@out_list = map { ACTION } @in_list;

ภายในบล็อกการดำเนินการ ค่าปัจจุบันจะมีเป็น $_

เราต้องการให้การกระทำของเราค้นหาค่าที่เหมาะสมในแฮช หรือรวมข้อความแสดงข้อผิดพลาดหากไม่มีการแมปสำหรับสตริงอินพุต:

my @letters = map { $morsecode{$_} // "<unknown code $_>" } @message;

สิ่งนี้ถือว่า ! ได้รับการลงทะเบียนเป็นช่องว่างในแฮชรหัสมอร์ส

จากนั้นเราสร้างสตริงเดียวของตัวอักษรเหล่านี้โดย joining ด้วยสตริงว่าง:

my $translated_message = join "", @letters;

และอย่าลืมพิมพ์ผลลัพธ์ออกมา!


รหัสที่สมบูรณ์:

#!/usr/bin/perl
use strict; use warnings; use 5.012;

my %morsecode=(
  '.-'    =>'A',  '-...'  =>'B',  '-.-.'  =>'C',  '-..'   =>'D',
  '.'     =>'E',  '..-.'  =>'F',  '--.'   =>'G',  '....'  =>'H',
  '..'    =>'I',  '.---'  =>'J',  '-.-'   =>'K',  '.-..'  =>'L',
  '--'    =>'M',  '-.'    =>'N',  '---'   =>'O',  '.--.'  =>'P',
  '--.-'  =>'Q',  '.-.'   =>'R',  '...'   =>'S',  '-'     =>'T',
  '..-'   =>'U',  '...-'  =>'V',  '.--'   =>'W',  '-..-'  =>'X',
  '-.--'  =>'Y',  '--..'  =>'Z',  '.----' =>'1',  '..---' =>'2',
  '...--' =>'3',  '....-' =>'4',  '.....' =>'5',  '-....' =>'6',
  '--...' =>'7',  '---..' =>'8',  '----.' =>'9',  '-----' =>'0',
  '.-.-.-'=>'.',  '--..--'=>',',  '---...'=>':',  '..--..'=>'?',
  '.----.'=>'\'', '-...-' =>'-',  '-..-.' =>'/',  '.-..-.'=>'"',
  '!'     =>' ',
);

say "Please type in your morse message:";
my @codes = <>;
chomp @codes;

my $message = join "", map { $morsecode{$_} // "<unknown code $_>" } @codes;

say "You said:";
say $message;

สิ่งนี้จะสร้างผลลัพธ์ที่ต้องการ

person amon    schedule 25.01.2013
comment
สิ่งนี้จะสร้างเอาต์พุตที่ต้องการ ... หากอักขระทุกตัวอยู่ในบรรทัดแยกกัน? - person mob; 26.01.2013
comment
@mob เป็นไปตามรูปแบบอินพุตที่ระบุโดย OP ผลลัพธ์ไม่มีการขึ้นบรรทัดใหม่ - person amon; 26.01.2013
comment
ดี! เรียนรู้มากกว่าที่ฉันคาดหวัง คำอธิบายที่ดี - person JLott; 26.01.2013

การเรียนรู้วิธีและวิธีการและเหตุผลมีคุณค่าอย่างมาก แต่สิ่งสำคัญมีดังนี้:

sub encode {
  my $output;
  foreach my $symbol (@_) {
    my $letter = $morsecode{$symbol};
    die "Don't know how to decode $symbol" unless defined $letter;
    $output .= $letter
  }
  return $output;
}

หรือแม้แต่ sub encode { join '', map $morsecode{$_}, @_ } เพียงเล็กน้อยหากคุณไม่กังวลเกี่ยวกับการตรวจสอบข้อผิดพลาดจนเกินไป @k และ @v ไม่จำเป็นสำหรับสิ่งใดๆ

person hobbs    schedule 25.01.2013

การค้นหาค่าในแฮชเป็นงานที่เข้มข้นมาก คุณจะดีกว่าโดยใช้แฮชแบบย้อนกลับ คุณสามารถย้อนกลับแฮชได้อย่างง่ายดายด้วย ฟังก์ชันย้อนกลับ ในภาษา Perl นอกจากนี้ ขณะที่ดูโค้ดของคุณ ฉันเห็นว่าคุณจะสามารถป้อนข้อมูลด้วยตัวพิมพ์เล็กได้ แต่ในขณะที่ค้นหาด้วยแฮชบนคีย์ จะคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ดังนั้น คุณจะต้อง ตัวพิมพ์ใหญ่ ข้อมูลที่คุณป้อน นอกจากนี้ฉันไม่ชอบวิธี "สิ้นสุด" STDIN มากนัก คำ/เครื่องหมายทางออกจะดีกว่าและสะอาดกว่า

ฉันใช้เวลากับรหัสของคุณ

my %morsecode=(
    '.-'    =>'A',  '-...'  =>'B',  '-.-.'  =>'C',  '-..'   =>'D',
    '.' =>'E',  '..-.'  =>'F',  '--.'   =>'G',  '....'  =>'H',
    '..'    =>'I',  '.---'  =>'J',  '-.-'   =>'K',  '.-..'  =>'L',
    '--'    =>'M',  '-.'    =>'N',  '---'   =>'O',  '.--.'  =>'P',
    '--.-'  =>'Q',  '.-.'   =>'R',  '...'   =>'S',  '-' =>'T',
    '..-'   =>'U',  '...-'  =>'V',  '.--'   =>'W',  '-..-'  =>'X',
    '-.--'  =>'Y',  '--..'  =>'Z',  '.----' =>'1',  '..---' =>'2',
    '...--' =>'3',  '....-' =>'4',  '.....' =>'5',  '-....' =>'6',
    '--...' =>'7',  '---..' =>'8',  '----.' =>'9',  '-----' =>'0',
    '.-.-.-'=>'.',  '--..--'=>',',  '---...'=>':',  '..--..'=>'?',
    '.----.'=>'\'', '-...-' =>'-',  '-..-.' =>'/',  '.-..-.'=>'\"'
);
my %reversemorse = reverse %morsecode;
print "Enter a message\n";
chomp (my $message = <STDIN>);
print &encode($message);

sub encode{
    my $origmsg = shift(@_);
    my @letters = split('',$origmsg);
    my $morse = '';
    foreach $l(@letters)
    {
        $morse .= $reversemorse{uc($l)}." ";
    }    
    return $morse;
}
person Tom    schedule 25.01.2013