2011-03-05 20 views
1

やあみんな、 は私がperlで2番目の単語で

Steve Blenheim:239-923-7366:238-934-7865:95 Latham Lane, Easton, PA 83755:11/12/56:20300 
Betty Boop:245-836-8357:245-876-7656:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500 
Igor Chevsky:385-375-8395:385-333-8976:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400 
Norma Corder:397-857-2735:397-857-7651:74 Pine Street, Dearborn, MI 23874:3/28/45:245700 

そして、私は2番目の単語からアルファベットの逆順でのテキスト(姓)を並べ替えるしようとしています電話帳と呼ばれるこのファイルを持っていないの並べ替えそれを行う方法を見つけることができました。私はこれを行うことでファイルから読んでいます

アイデア?私は最初のフィールドをアルファベット順に並べ替えることができますが、2番目のフィールドを適切に並べ替えることはできません。 ありがとうございます

+5

ボブに基づいて「Billy Bob Thorton」をソートしますか?マーティン・ルーサー・キング・ジュニア(Martin Luther King Jr)は、「マーティン」に基づいていますか?ソートは簡単です。どの姓が姓であるかを判断する方法は難しいです... – tadmc

答えて

2

シェルを使用しても構わない場合、sort -r -k2は逆の順序でファイルをソートします。

0

これを行うには、ファイルを1行ずつ読む必要があります。このような何か:

my %list; 
open(FILE, phonebook); 
while(<FILE>){ 
    my @vals = split(/:/, $_); 
    (my $key = $vals[0]) =~ s/(\S+)\s+(.+)/$2 $1/; # split first field, reverse word order 
    $list{$key} = $_; #save row keyed on $key 
} 

foreach my $key(sort {$b cmp $a} keys(%list)){ 
    print $list{$key}; 
} 
+0

2番目のフィールドが重複しているかどうかはわかりません。 ) – hobbs

+0

@hobbs:しかし、私の例では、最初のコロンで区切られたフィールドの2番目と最後のすべての単語、スペース、最初の単語がこの例の電話帳で重複している場合、すべてのベットはオフになっています。 – RET

+0

ああ、それはやってもいいけど、大丈夫だよ。 – hobbs

10

私は空白で2番目のフィールドは、常に姓になるだろうが、それは2番目のフィールドに関連するとして、あなたはsplitを使用してそれを得ることができ、質問に答えていないことをtadmcの懸念を共有します

シンプルだがひどく遅い(読みやすいが、2つの行を比較するたびにすべてのフィールドが再分割されるため、非効率的である)。

@lines = sort { # Compare second fields 
    (split " ", $a)[1] 
    cmp 
    (split " ", $b)[1] 
} @lines; 

Schwartzian transformバージョン(だけはるかに速く、以前のものとまったく同じことを行い):

@lines = map { # Get original line back 
    $_->[0] 
} sort { # Compare second fields 
    $a->[1] cmp $b->[1] 
} map { # Turn each line into [original line, second field] 
    [ $_, (split " ", $_)[1] ] 
} @lines; 
+0

+1 +1となります。 – converter42

0

私はそれが(溶液が同じである近代的なPerlのように書くことは興味深いことだと思います)、これは完全なスクリプトです:

use strict; 

open my $FILE, '<', 'phonebook'; 
my @lines = <$FILE>; 

my @sorted = sort { 
       my @a = split(/\s+/,$a); 
       my @b = split(/\s+/,$b); 
       $b[1] cmp $a[1] } @lines; 

foreach my $item(@sorted) { 
    print "$item\n"; 
} 

close $FILE; 
+0

'strict'と3つの引数' open'字句ファイル鼻。あなたのコードにはいくつかの問題があります。まず、タイプミスがあります。ソートブロック上の閉じ括弧が欠けていて、 '@lines'配列ではフィードしませんでした。第2に、並べ替えは高価な演算であり、最悪の場合はO(n)、平均O(n * log n)のときは最高O(n)で実行されます。これは、あなたが**多くの**比較を行い、そのたびにキーワードを再分割することを意味します。検索語を事前に計算する方がよいでしょう。 Schwartzian Transformを使うか、中間変数を使うことができます。それは実際に事前計算することに支払う。 – daotoad

0

私は誰もがこれを言及していない驚いて、私たちは電話帳をソートしている場合、我々はおそらく、本当に純粋なASCIIの並べ替えをしたくありません。

Bob DeCarloは本当にRalph Dearbornの前に属していますか? cmpを使用して並べ替えると、DeCarlo氏が最初に結果を表示します。

ケースを正規化しても、まだ問題があります。ソートや提出には複雑な問題があります。異なるorganizations have rulesの場合はhandlingこれらの問題。

ソートは高価な操作なので、できるだけ早く各比較作業を行う必要があります。これを行う方法は、すべての比較で可能な最もシンプルなコードを使用することです。 cmpは、それ自身では望みの結果を得られないので、電話帳の各項目の正規化ソート項を生成してキャッシュする必要があります。だから、

、すでに配列にあなたの電話帳データを持っていると仮定すると:

sub extract_and_normalize { 
    # Do stuff here to embody your alphabetization rules. 

    return [ $normed, $line ]; 
} 

# Generate your sort terms 
my @processed = map extract_and_normalize($_), @lines; 

# Sort by the normalized values 
my @sorted = sort {$a->[0] cmp $b->[0]}, @processed; 

# Extract the lines from the sorted set. 
@lines = map $_->[1], @sorted; 

それともhobbsは、すべての中間変数を避けるために、示唆するように、変換シュワルツを使用します。

@lines = map $_->[1], 
     sort { $a->[0] cmp $b->[0] } 
     map extract_and_normalize($_), @lines; 
2

Miguel Przの解決策に基づき、私は 'cmd'を '< =>'に置き換えました。 数字にとっては重要です。 CMPを使用すると、並べ替えは文字列(数字)として機能します。最初の文字が最も重要で、次に2番目の文字が続きます。数値が607,8および35の場合、CMPはそれを8,607,35としてソートします。数値としてソートするには、「< =>」メソッドを使用し、結果は次のようになります。607,35,800

use strict; 

open my $FILE, '<', 'phonebook'; 
my @lines = <$FILE>; 

my @sorted = sort { 
       my @a = split(/\s+/,$a); 
       my @b = split(/\s+/,$b); 
       $b[1] <=> $a[1] } @lines; 

foreach my $item(@sorted) { 
    print "$item\n"; 
} 

close $FILE; 
+0

これは質問された質問に答えません。サンプル入力の各行の2番目のフィールド( 'split/\ s + /')は、 "Blenheim"、 "Boop"、 "Chevsky"、 "Corder"です。それらのすべては '<=>'を使用して等しいと比較されます。 – hobbs

関連する問題