16

その単語の文字を並べ替えて別の単語を形成できる場合、その単語はアナグラムです。

仕事:

  • 与えられた単語リストからアナグラムのすべてのセットを見つけるための、文字数による最短のソース コード。

  • スペースと改行は文字としてカウントする必要があります

  • コード定規を使う

    ---------10--------20--------30--------40--------50---- ----60--------70--------80--------90--------100-------110- ------120

入力:

各単語が改行で区切られた stdin からの単語のリスト。

例えば

A
A's
AOL
AOL's
Aachen
Aachen's
Aaliyah
Aaliyah's
Aaron
Aaron's
Abbas
Abbasid
Abbasid's

出力:

アナグラムのすべてのセット。各セットは個別の行で区切られています。

実行例:

./anagram < words
marcos caroms macros
lump's plum's
dewar's wader's
postman tampons
dent tend
macho mocha
stoker's stroke's
hops posh shop
chasity scythia
...

私は149文字のperlソリューションを持っており、さらに数人が投稿するとすぐに投稿します:)

楽しむ!

編集:説明

  • アナグラムは大文字と小文字を区別しないと仮定します (つまり、大文字と小文字は同等です)。
  • 複数のアイテムを含むセットのみを印刷する必要があります
  • アナグラムの各セットは一度だけ印刷する必要があります
  • アナグラム セット内の各単語は 1 回だけ出現する必要があります

EDIT2: さらなる説明

  • 2 つの単語の大文字と小文字のみが異なる場合は、それらを同じ単語に折りたたむ必要があります。折りたたまれた単語に使用する大文字と小文字のスキームを決定するのはユーザー次第です。
  • 単語のセットは、各単語が何らかの方法で区切られている限り (コンマ区切りやスペース区切りが有効である限り)、新しい行で終了する必要があります。一部の言語にはクイック配列印刷メソッドが組み込まれていることを理解しています。これにより、スペースで区切られた配列を出力しない場合にそれを利用できるはずです。
4

8 に答える 8

12

Perl、59 文字

chop,$_{join'',sort split//,lc}.="$_ "for<>;/ ./&&say for%_

これには Perl 5.10 (say関数用) が必要であることに注意してください。

于 2010-04-02T16:28:49.257 に答える
12

パワーシェル、104 97 91 8683文字

$k=@{};$input|%{$k["$([char[]]$_|%{$_+0}|sort)"]+=@($_)}
$k.Values|?{$_[1]}|%{"$_"}

新しい要件の更新 (+8 文字):

大文字と小文字のみが異なる単語を除外するには、入力リストから重複を (大文字と小文字を区別せずに) 削除するだけです。つまり$input|sort -u、 where-uは を表し-uniqueます。sortデフォルトでは大文字と小文字を区別しません:

$k=@{};$input|sort -u|%{$k["$([char[]]$_|%{$_+0}|sort)"]+=@($_)} 
$k.Values|?{$_[1]}|%{"$_"} 

[char[]]$_|%{$_+0}|sort~の部分の説明

これは、単語のアナグラムが格納されるハッシュテーブル エントリのキーです。私の最初の解決策は次のとおり$_.ToLower().ToCharArray()|sortです。その後ToLower()、ハッシュテーブルの検索では大文字と小文字が区別されないため、キーは必要ないことがわかりました。

[char[]]$_|sort理想的ですが、キーの文字の並べ替えでは大文字と小文字を区別する必要があります (そうCabしないとabc、別のキーに格納されます)。残念ながら、sort文字の場合は大文字と小文字を区別しません (文字列のみ)。

必要なのは ですが[string[]][char[]]$_|sort、各文字を文字列に変換するより短い方法を見つけました。これは、何か他のもの、この場合は整数0、したがってを連結することです[char[]]$_|%{$_+0}|sort。これはソート順には影響せず、実際のキーは次のようになりますd0 o0 r0 w0。それはきれいではありませんが、それは仕事をします:)

于 2010-04-02T12:22:09.703 に答える
5

Haskell、147 文字

以前のサイズ:150 159文字

import Char
import List
x=sort.map toLower
g&a=g(x a).x
main=interact$unlines.map unwords.filter((>1).length).groupBy((==)&).sortBy(compare&).lines

このバージョンは、165 文字で、新しく明確化されたルールを満たしています。

import Char
import List
y=map toLower
x=sort.y
g&f=(.f).g.f
w[_]="";w a=show a++"\n"
main=interact$concatMap(w.nubBy((==)&y)).groupBy((==)&x).sortBy(compare&x).lines

このバージョンは以下を処理します。

  1. 大文字と小文字のみが異なる入力内の単語は、1 単語としてカウントする必要があります
  2. 出力は 1 行に 1 つのアナグラム セットである必要がありますが、余分な句読点は許容されます
于 2010-04-02T14:20:35.743 に答える
4

ルビー、94文字

h={};(h[$_.upcase.bytes.sort]||=[])<<$_ while gets&&chomp;h.each{|k,v|puts v.join' 'if v.at 1}
于 2010-04-02T13:33:48.910 に答える
3

Python、167文字、I/Oを含む

import sys
d={}
for l in sys.stdin.readlines():
 l=l[:-1]
 k=''.join(sorted(l)).lower()
 d[k]=d.pop(k,[])+[l]
for k in d:
 if len(d[k])>1: print(' '.join(d[k]))

入力コードがない場合(つまり、すでにリストにあるワードリストを想定している場合w)、わずか134文字です。

d={}
for l in w:
 l=l[:-1]
 k=''.join(lower(sorted(l)))
 d[k]=d.pop(k,[])+[l]
for k in d:
 if len(d[k])>1: print(' '.join(d[k]))
于 2010-04-02T10:03:22.193 に答える
2

AWK-119

{split(toupper($1),a,"");asort(a);s="";for(i=1;a[i];)s=a[i++]s;x[s]=x[s]$1" "}
END{for(i in x)if(x[i]~/ .* /)print x[i]}

joinAWK にはPython のような機能がありません。

大文字と小文字は異なるものとみなします。

于 2010-04-02T10:33:55.403 に答える
2

C++、542 文字

#include <iostream>
#include <map>
#include <vector>
#include <boost/algorithm/string.hpp>
#define ci const_iterator
int main(){using namespace std;typedef string s;typedef vector<s> vs;vs l;
copy(istream_iterator<s>(cin),istream_iterator<s>(),back_inserter(l));map<s, vs> r;
for (vs::ci i=l.begin(),e=l.end();i!=e;++i){s a=boost::to_lower_copy(*i);
sort(a.begin(),a.end());r[a].push_back(*i);}for (map<s,vs>::ci i=r.begin(),e=r.end();
i!=e;++i)if(i->second.size()>1)*copy(i->second.begin(),i->second.end(),
ostream_iterator<s>(cout," "))="\n";}
于 2010-04-02T14:57:48.233 に答える
1

Python、O(n ^ 2)

import sys;
words=sys.stdin.readlines()
def s(x):return sorted(x.lower());
print '\n'.join([''.join([a.replace('\n',' ') for a in words if(s(a)==s(w))]) for w in words])
于 2010-04-02T10:01:51.633 に答える