寻找字符串' "置换"基于字母顺序

时间:2016-12-06 00:30:24

标签: java string permutation

我想征求意见,如果有更有效的方法来找到字符串'基于字母顺序的排列,如下面的代码。 我使用长达16个字符的字符串和大量数据,并且运行我的程序需要花费太多时间和内存。

问题的基本表示

输入:字母

输出:16752348

所以在单词" alphabet"信' a'是字母表中的第一个,标记为索引1,然后是另一个' a'在第五个位置,标记为2,然后来到' b'在第六个位置,标记为3,依此类推。

在代码中我不使用数字作为索引,而不是使用字符,因此从ASCII值的值65开始。 (因为我使用测试长字符串。但它并没有改变主要目的)。所以我的程序的输出将是

输入:字母

输出:AFGEBCDH

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(
            "<connection string>",
            options => options.EnableRetryOnFailure());
}

3 个答案:

答案 0 :(得分:0)

WRT内存利用率,你粘贴的程序不会使用太多。您在实际代码中使用返回的字符串做什么?

就性能而言,这应该会更好一点:

import java.util.Arrays;

class El implements Comparable<El>{
 char c;
 int idx;

 public El(char c, int idx) {
  this.c = c;
  this.idx = idx;
 }

 public int compareTo(El other) {
   return Character.compare(c, other.c);
 }
}

public class Perm {
  public static String perm(String word){
    int l = word.length();
    El[] els = new El[l];
    for (int i=0; i<l; i++) {
      els[i] = new El(word.charAt(i), i);
    }
    Arrays.sort(els);
    StringBuilder sb = new StringBuilder(l);
    for (int i=0; i<els.length; i++) {
      sb.append((char)('A' + els[i].idx));
    }
    return sb.toString();
  }

  public static void main (String [] args){
    System.out.println(perm("alphabet"));
  }
}

答案 1 :(得分:0)

试试这个:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class alphabet {
    public static List<CharIndexHolder> charlist = new ArrayList<CharIndexHolder>();

    public static String perm(String word) {
        char[] perm = new char[word.length()];
        char[] wordArray = word.toCharArray();
        char[] sortedWord = new char[word.length()];

        sortedWord = word.toCharArray();
        Arrays.sort(sortedWord);

        for (int i=0; i<word.length(); i++){
            for (int j=0; j<word.length(); j++){

                if (sortedWord[i] == wordArray[j]){
                    perm[j] = (char)(65+i);  //from A
                    wordArray[j] = '.';

                    j = word.length();    //in case, if the word has more of the tested char, we jump to the end of the cycle
                }
            }
        }   
        return String.valueOf(perm);
    }

    public static String perm2(String word) {
        charlist.clear();
        for(int i = 0; i < word.length(); i++) {
            charlist.add(new CharIndexHolder(word.charAt(i), i));
        }
        Collections.sort(charlist);
        for(int i = 0; i < charlist.size(); i++) {
            charlist.get(i).assignedindex = i;
        }
        char[] result = new char[word.length()];
        for(int i = 0; i < result.length; i++) {
            CharIndexHolder cur = charlist.get(i);
            result[cur.index] =(char) (charlist.get(i).assignedindex + 65);
        }
        return new String(result);
    }

    public static void main (String [] args){
        System.out.println(perm("alphabet"));
        System.out.println(perm2("alphabet"));
    }
}

助手类:

public class CharIndexHolder implements Comparable<CharIndexHolder> {
    public int index;
    private char character;
    public int assignedindex;

    CharIndexHolder(Character character, int index) {
        this.character = character;
        this.index = index;
    }

    @Override
    public int compareTo(CharIndexHolder o) {
        if(this.character < o.character) {
            return -1;
        }
        if(this.character > o.character) {
            return 1;
        }
        if(this.index < o.index) {
            return -1;
        }
        if(this.index > o.index) {
            return 1;
        }
        return 0;
    }       
}

我想不出比N * log(n)更快的方法。如果您需要更高的速度,请尝试使用长数组替换列表,但每批次只分配一次数组(每次调用不分配一次)。

答案 2 :(得分:0)

我查看了我之前的解决方案,看起来Arrays.sort()对于一个可比较的数组需要比原始类型数组长得多。 我尝试了几种方法,以下是为大量单词提供更少时间的方法:

  public static String perm(String word){
    int l = word.length();
    int[] els = new int[l];
    for (int i=0; i<l; i++) {
      els[i] = (word.charAt(i) << 16) | i;
    }
    Arrays.sort(els);
    char[] sb = new char[l];
    for (int i=0; i<els.length; i++) {
      sb[i] = (char)('A' + els[i] & 0xFFFF);
    }
    return String.valueOf(sb);
  }

请注意,该方法隐含式假设单词仅使用UTF-16编码的低15位(对于英文字母中的单词,则为true)。

就内存利用率而言,您必须要小心使用Java测量的内容。内存利用率可能在一种方法与另一种方法中出现峰值的事实不一定是一个好的指标,因为该内存可能是垃圾收集的。这里的所有方法都使用临时数组/对象,这些数组/对象在执行perm()之后可用于垃圾回收(除了返回的字符串)。现在,如果你关心减少内存利用率以减少垃圾收集(从而提高性能),我怀疑最后一种方法应该会给出好的结果,尽管我没有测量过。