[英]Generating the lexicographically greatest string
問題是在給定字符串s的情況下生成按字典順序排列的最大字符串。 因此,目標是從s中找到字典上最大的,唯一的(無重復)子串s1。 我們說如果s1的字符多於s2,則某些子序列s1大於另一個子序列s2,或者如果s1等於長度,則s1的字典大於s2。
I / O如下:
輸入是: ba bab
輸出是:ba
第二個輸入是:nlhthgrfdnnlprjtecpdr t higjoqdejsfka soc tjijaoebql r gaiakfsbljm p ib k id j srtk g r d n q sk nb arp a bgokbsr fhm eklr le
第二個輸出是:tsocrpkijgdqnbafhmle
這是我為我的java代碼編寫的,但我的代碼在第二個測試用例上失敗了。 此外,我很難理解為什么第二個輸出不是tsrqponmlkjihgfedcba。 有人可以提供修復甚至java代碼的建議嗎?
我認為算法必須比生成所有可能的唯一字符串更有效,對它們進行排序並找到按字典順序排列的最大字符串。
為了使問題更清楚,如果輸入是babab,則所有可能的唯一組合將是b,a,ba,ab。 輸出將是ba,因為它是最長的,並且在詞典上大於ab。
注意:這不是家庭作業。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class mostBeautiful {
final static int MAX = 1000000;
static String[] permute;
static void permutation(String prefix, String str, int counter) {
int n = str.length();
//System.out.println("n is: "+ n);
if (n == 0) {
permute[counter] = prefix;
} else {
for (int i = 0; i < n; i++) {
//System.out.println("str is: "+ str);
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n), counter++);
}
}
}
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String s = bf.readLine();
char[] unique = new char[26];
int counter = 0;
String answer = "";
//System.out.println("s is: " + s);
int ascii = 0;
final int asciiAVal = 97;
final int asciiZVal = 122;
for (int i = 0; i < s.length(); i++) {
ascii = (int)s.charAt(i);
if (ascii < asciiAVal || ascii > asciiZVal) {
continue;
}
char ch = s.charAt(i);
unique[ch - 'a'] = ch;
}
String result = "";
for (int j = 25; j >= 0; j--) {
result += unique[j];
}
result = result.trim();
System.out.println(result);
int size = result.length() * (result.length() - 1);
permute = new String[size];
permutation("", result, counter);
for (int i = 1; i < size; i++) {
if (permute[i].compareTo(permute[i - 1]) > 0){
answer = permute[i];
} else {
answer = permute[i - 1];
}
}
System.out.println("answer is: " + answer);
}
}
在以多種方式思考這個問題后,我已經確定了一種分而治之的算法,可以得到正確的結果:
假設一些輸入字符串,S定義為兩個子串A + B的串聯,我們遞歸地計算字典順序最大的字符串:
LexMax(S) = Merge(LexMax(A),LexMax(B))
哪里
LexMax(S)
{
if Length(S) = 1
return S
else
{
LMA = LexMax(S[0:Length/2])
LMB = LexMax(S[Length/2:end])
return Merge(LMA,LMB)
}
}
Merge(A,B)
{
Sa = A
Sb = B
for n = 0:Length(A)
{
if Sb contains A[n]
{
if A[n+1:end] contains character > A[n]
Remove A[n] from Sa
else
Remove A[n] from Sb
}
}
return Sa + Sb
}
快來了!
給定一個輸入字符串
cefcfdabbcfed
把它分成
cefcfda
bbcfed
假設功能有效,我們有:
LexMax("cefcfda") = "efcda"
LexMax("bbcfed") = "bcfed"
合並的工作原理如下:
e: efcda bcfed
在兩個子串中,在左子串中找到e右側的值越大,從左側移除
f: fcda bcfed
在兩個子字符串中,左子字符串中沒有更大的值,從右側刪除
c: fcda bced
在兩個子字符串中,左側子字符串中的c右側找到更大的值,從左側刪除
d: fda bced
在兩個子字符串中,左子字符串中沒有更大的值,從右側刪除
a: fda bce
不在兩個子串中,什么都不做
最后結果:
LexMax(cefcfdabbcfed) = fdabce
這不是一個直接的答案,但是這個代碼是否符合您在上面討論中解釋的要求?
final String x = "saontehusanoethusnaoteusnaoetuh";
final SortedSet<Character> chars =
new TreeSet<Character>(Collections.reverseOrder());
for (char c : x.toCharArray()) chars.add(c);
System.out.println(chars);
字典順序是一種順序,其中單詞使用單詞中字母的外觀按字母順序顯示。它也被稱為字典順序或字母順序。例如: - “非洲”小於“孟加拉國”,“他”小於“他”。
public class LexicographicExample {
public static void main(String a[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the String:-");
String str = sc.nextLine();
System.out.println("Enter the length");
int count = sc.nextInt();
List<String> list = new ArrayList<String>();
for (int i = 0; i < str.length(); i = i + 1) {
if (str.length() - i >= count) {
list.add(str.substring(i, count + i));
}
}
Collections.sort(list);
System.out.println("Smallest subString:-" + list.get(0));
System.out.println("Largest subString:-" + list.get(list.size() - 1));
}
}
如需參考,請參閱此鏈接http://techno-terminal.blogspot.in/2015/09/java-program-to-find-lexicographically.html
“tsrqponmlkjihgfedcba”不是答案,因為它不是輸入的后續序列。 子序列的定義要求子序列的字符以相同的順序出現在原始序列中 。 例如,“abc”是“apbqcr”的子序列,而“cba”則不是。
至於解決方案,我認為一個簡單的貪婪算法就足夠了。 首先,必須理解輸出的最大可能長度是輸入中唯一符號(例如,N)的數量。 由於任何短於此的輸出都不是最大的輸出,因此它必須是N個符號長。 其余的過程很簡單,時間復雜度至多是二次方:一個必須通過輸入字符串,並在每一步選擇字典上最高的符號,使其左側的字符串部分仍然包含所有“未使用的“符號。
例如,考慮一個字符串“bacb”。 第一個符號可以是'a'或'b',因為在兩種情況下,余數都包含其他兩個字母。 'b'更大,所以我們選擇它。 現在對於“acb”我們只能根據那個條件選擇'a'而不是'c',所以我們最終輸出“bac”。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
class aaa {
public static void main(String args[]) throws Exception {
Scanner scan = new Scanner(System.in);
// int n = scan.nextInt();
String s = scan.next();
HashMap<Character, Node5> map = new HashMap<>();
for (int i = 0; i < s.length(); i++) {
if (!map.containsKey(s.charAt(i))) {
Node5 node = new Node5();
node.nl.add(i);
node.li = i;
map.put(s.charAt(i), node);
} else {
Node5 rn = map.get(s.charAt(i));
rn.nl.add(i);
rn.li = i;
map.put(s.charAt(i), rn);
}
}
String s1 = "";
int index = -1;
for (int i = 25; i >= 0; i--) {
if (map.containsKey((char) (97 + i))) {
if (map.get((char) (97 + i)).li > index) {
for (int j = 0; j < map.get((char) (97 + i)).nl.size(); j++) {
if (map.get((char) (97 + i)).nl.get(j) > index) {
s1 += (char) (97 + i);
index = map.get((char) (97 + i)).nl.get(j);
}
}
}
}
}
System.out.println(s1);
scan.close();
}
}
class Node5 {
int li;
ArrayList<Integer> nl;
public Node5() {
this.nl = new ArrayList<>();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.