词典排序

时间:2011-01-08 06:30:23

标签: algorithm lexicographic

我正在做一个问题,说“连接单词以生成按字典顺序排列的最低字符串。”来自比赛。

以此字符串为例:jibw ji jp bw jibw

实际输出结果为:bw jibw jibw ji jp

当我对此进行排序时,我得到:bw ji jibw jibw jp

这是否意味着这不是排序?如果是排序,“词典”排序是否考虑将较短的琴弦推到后面或其他东西?

我一直在lexigographical order上做一些阅读,我没有看到使用它的任何点或场景,你有吗?

10 个答案:

答案 0 :(得分:25)

您正在寻找的是对问题的更好理解,所以让我说清楚。字符串上的常规排序是词典排序。如果您将字符串[jibw,ji,jp,bw,jibw]排序为字典顺序,则排序的序列 [bw,ji,jibw,jibw,jp],这就是你得到的。所以你的问题不在于理解“词典”这个词;你已经正确理解了它。

你的问题是你误解了这个问题。问题不是要求您按字典顺序排序字符串。 (如果确实如此,那么通过排序得到的答案是正确的。)相反,它会要求您生成一个字符串,通过以某种顺序连接输入字符串得到(即,使一个字符串没有空格),以便得到的单个字符串在字典上最小。

为了说明差异,请考虑通过连接排序序列和答案字符串获得的字符串:

bwjijibwjibwjp //Your answer
bwjibwjibwjijp //The correct answer

现在,当你比较这两个字符串时 - 请注意,你只是比较两个14个字符的字符串,而不是两个字符串序列 - 你可以看到正确的答案确实在字典上小于你的答案:你的答案从“ bwjij“,而正确的答案以”bwjib“开头,”bwjib“以字典顺序出现在”bwjij“之前。

希望你现在明白这个问题。这根本不是一个排序问题。 (也就是说,排序输入字符串不是问题。你可以对通过置换和连接输入字符串获得的所有可能字符串进行排序;这是解决问题的一种方法输入字符串很小。)

答案 1 :(得分: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

将此比较功能与标准排序一起使用可以解决问题。

答案 2 :(得分:1)

我一直在这个Facebook黑客杯中使用F#。在这次比赛中学到了很多东西。由于关于网络上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

答案 3 :(得分:1)

//使用此代码块打印数组的按字典顺序排序的字符,或者可以以多种方式使用它。

  #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);
        }
    }

答案 4 :(得分:0)

您发布的示例显示仅仅排序不会生成按字典顺序排列的最低字符串。 对于给定的问题,您需要应用一些额外的技巧来确定哪个字符串应该在哪个字符串之前(截至目前,我无法想到确切的方法)

实际输出不违反按字典顺序排列的最低字的条件。

答案 5 :(得分:0)

linux上的sort命令也进行Lexicographic排序并按顺序生成输出bw ji jibw jibw jp

答案 6 :(得分:0)

检查这里发生了什么:

如果您只是应用词典排序,那么您将获得bw ji jibw jibw jp 但是如果你通过令牌分析令牌,你会发现“bwjibw”(bw,jibw)的词典比lewographicalyaly低于“bwjijibw”(bw,ji,jibw)这就是为什么答案是bw jibw jibw ji jp,因为首先你应该追加bwjibwjibw然后你可以连接ji和jp来获得最低的字符串。

答案 7 :(得分:0)

一个简单的技巧,只涉及排序,这可以解决这个问题,因为指定了最大字符串长度,将填充所有字符串,最大长度为字符串中的第一个字母。然后对填充的字符串进行排序,但输出原始未填充的字符串。对于前者对于字符串长度2和输入b和ba你会排序bb和ba,它会给你ba和bb,因此你应该输出bab。

答案 8 :(得分:0)

如果您使用特殊的“占位符”字符填充Prasun的技巧,可以在字符串排序函数中将其加权为大于“z”。结果将为您提供最低词典组合的顺序。

答案 9 :(得分:0)

比赛已结束,所以我发布了一个可能的解决方案,而不是最有效但一种方式

 #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函数只是生成按字典顺序排列的排列