質問
私は「単語を連結して、辞書編集的に最も低い可能な文字列を生成する」という問題を遂げています。競争から。
たとえば、この文字列を考えてみましょう。 jibw ji jp bw jibw
実際の出力は次のことが判明しました: bw jibw jibw ji jp
これについて並べ替えると、 bw ji jibw jibw jp
.
これは、これがソートではないことを意味しますか?それが選別されている場合、「レキシグラフィー」ソートは、より短い文字列を背中か何かに押し込むことを考慮していますか?
私は読書をしてきました 語彙順序 そして、これが使用されるポイントやシナリオはありませんが、何かありますか?
解決
あなたが探しているのは質問をよりよく理解しているようですので、それを明確にしましょう。文字列の通常のソート は 辞書編集の並べ替え。文字列[Jibw、Ji、JP、BW、Jibw]を辞書編集順に並べ替えた場合、ソートされたシーケンス は bw、ji、jibw、jibw、jp]、これがあなたが得たものです。したがって、あなたの問題は「辞書誌」という言葉を理解することではありません。あなたはすでにそれを正しく理解しています。
あなたの問題は、あなたが質問を誤解していることです。質問はあなたに尋ねません 選別 辞書編集の文字列。 (もしそうなら、並べ替えによって得た答えは正しいでしょう。)代わりに、それはあなたに作成するように頼みます 1 文字列、手に入れた 連結 入力文字列は、ある順序で文字列(つまり、スペースなしで1つの文字列を作成します)で、結果の単一の文字列が辞書的に最小限になるようにします。
違いを説明するには、ソートされたシーケンスを連結することで得られる文字列と、回答文字列を考慮してください。
bwjijibwjibwjp //Your answer
bwjibwjibwjijp //The correct answer
ここで、これらの2つの文字列を比較すると、2つの文字列ではなく2つの14文字の文字列を比較しているだけで、正解は実際に辞書的に答えよりも小さいことがわかります。答えは「bwjij」から始まります。正しい答えは「bwjib」から始まり、「bwjib」は辞書編集の順序で「bwjij」の前に来ます。
あなたが今質問を理解していることを願っています。ソートの質問ではありません。 (つまり、それは入力文字列を並べ替える問題ではありません。あなたは たぶん......だろう 入力文字列を順番に連結することで得られたすべての可能な文字列の並べ替えを行います。これは、入力文字列の数が小さい場合、問題を解決する1つの方法です。)
他のヒント
Word1 + word2をWord2 + word1と比較することにより、これを些細なソートの問題に変換できます。 Python:
def cmp_concetanate(word1, word2):
c1 = word1 + word2
c2 = word2 + word1
if c1 < c2:
return -1
elif c1 > c2:
return 1
else:
return 0
この比較関数を標準ソートと使用すると、問題が解決します。
このFacebookハッカーカップでF#を使用しています。この競争でかなり学びました。 Web上のF#のドキュメントはまだまれなので、ここで少し共有するかもしれないと思います。
この問題は、カスタマイズされた比較方法に基づいて文字列のリストを並べ替えることを要求します。これがF#の私のコードスニペットです。
let comparer (string1:string) (string2:string) =
String.Compare(string1 + string2, string2 + string1)
// Assume words is an array of strings that you read from the input
// Do inplace sorting there
Array.sortInPlaceWith comparer words
// result contains the string for output
let result = Array.fold (+) "" words
//このコードブロックを使用して、配列の辞書編集文字を印刷するか、さまざまな方法で使用できます。
#include<stdio.h>
#include<conio.h>
void combo(int,int,char[],char[],int*,int*,int*);
void main()
{
char a[4]={'a','b','c'};
char a1[10];
int i=0,no=0;
int l=0,j=0;
combo(0,3,a,a1,&j,&l,&no);
printf("%d",no);
getch();
}
void combo(int ctr,int n,char a[],char a1[],int*j,int*l,int*no)
{
int i=0;
if(ctr==n)
{
for(i=0;i<n;i++)
printf("%c",a1[i]);
printf("\n");
(*no)++;
(*j)++;
if((*j)==n)
{
*l=0;
*j=0;
}
else
*l=1;
getch();
}
else
for(i=0;i<n;i++)
{
if(*l!=1)
*j=i;
a1[ctr]=a[*j];
combo(ctr+1,n,a,a1,j,l,no);
}
}
あなたが投稿した例は、単なる並べ替えが辞書的に最も低い文字列を生成しないことを示しています。与えられた問題のために、あなたはいくつかの追加のトリックを適用して、どの文字列が来るべきかを判断する必要があります(今のところ、私は正確な方法を考えることはできません)
実際の出力は、辞書的に最も低い単語の条件に違反しません。
Linuxのソートコマンドは、辞書編集の並べ替えも行い、BW Ji Jibw Jibw JPの順序で出力を生成します
ここで何が起こったのかを確認してください:
レキシグラフィーの種類を適用するだけで、BW Ji Jibw Jibw JPを取得しますが、トークンによるトークンを分析すると、「bwjibw」(bw、jibw)は「bwjijibw」(bw、ji、jibw)よりも辞書的なものであることがわかります。そのため、答えはbw jibw jibw ji jpです。最初にbwjibwjibwを追加する必要があり、その後、JiとJPを連結して最低の文字列を取得できるためです。
最大文字列の長さが指定されているときにこの問題に役立つソートのみを含む簡単なトリックは、文字列の最初の文字ですべての文字列を最大長までパディングすることです。次に、パッド入りの弦を並べ替えますが、元の未処理の文字列を出力します。 exのために。文字列長2および入力BとBAの場合、BAとBBを提供するBBとBAをソートするため、BABを出力する必要があります。
Prasunのトリックは、文字列ソート関数の「Z」よりも大きくなるように重み付けされる可能性のある特別な「プレースホルダー」文字をパッドでパッドする場合に機能します。その結果、最も低い辞書編集の組み合わせの順序が得られます。
コンテストは終わったので、私は可能なソリューションを投稿していますが、最も効率的ではなく、それを行う1つの方法を投稿しています
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
ofstream myfile;
myfile.open("output.txt");
int numTestCases;
int numStrings;
string* ptr=NULL;
char*ptr2=NULL;
string tosort;
scanf("%d",&numTestCases);
for(int i=0;i<numTestCases;i++)
{
scanf("%d",&numStrings);
ptr=new string[numStrings];
for(int i=0;i<numStrings;i++)
{
cin>>ptr[i];
}
sort(ptr,ptr+numStrings);
for(int i=0;i<numStrings;i++)
{
next_permutation(ptr,ptr+numStrings);
}
tosort.clear();
for(int i=0;i<numStrings;i++)
{
tosort.append(ptr[i]);
}
ptr2=&tosort[i];
cout<<tosort<<endl;
myfile<<tosort<<endl;
delete[]ptr;
}
return 0;
}
C ++のSTLライブラリのアルゴリズムを使用しています。Prev_Permutation関数は単に辞書化された順列を生成するだけです