当前位置:网站首页>Concatenate strings to get the result with the smallest dictionary order
Concatenate strings to get the result with the smallest dictionary order
2022-07-01 16:47:00 【Bright morning light】
1、 subject
Given an array of strings strs
, You have to put all the strings together , Return to all possible splicing results , The result of minimum dictionary order .
2、 Ideas
Greedy strategy : Sort the strings in the array in dictionary order , Then splice them in order .
This strategy incorrect !!, Because there are counterexamples :["b", "ba"]
, Dictionary order b < ba
, The splicing string obtained according to the greedy strategy should be bba
, But actually bab
The result of this splicing is better than bba
Small .
// Failed greedy strategy
if (str1 < str2) //str1 Dictionary sequence < str2 Dictionary sequence
str1 before ;
else
str2 before ;
A really effective greedy strategy : Use the comparator to judge the dictionary order after the splicing of two strings
// If str1 Splicing str2 The following dictionary sequence < str2 Splicing str1 The following dictionary sequence
if (str1.str2 < str2.str1)
str1 before ;
else
str2 before ;
Why is this greedy strategy effective ? This requires proof .
First, we need to prove that the sorting strategy has Transitivity , The purpose is to prove that the string obtained under this sort of sorting strategy is unique .
Transitivity is to prove : according to (1)
a.b <= b.a
;(2)b.c <= c.b
, Can we deducea.c <= c.a
?Like strings
“123”
and“456”
, After splicing, it is“123456”
, If it isK
Base number , Then this splicing process is replaced by mathematical symbols “123” × \times × K3 + “456”.All strings can be regarded as numbers , Then it must be a nonnegative integer .
Further Abstract , Assume that all strings are
K
It's binary , that a.b = a × \times × Kb length + b, Further substitution ,m(x) = Kx length .So the first 1)2) Conditions can be rewritten :
a.b <= b.a
I could rewrite it as :a * m(b) + b <= b * m(a) + a
①b.c <= c.b
I could rewrite it as :b * m(c) + c <= c * m(b) + b
②① The left and right sides of the formula are reduced at the same time b, Multiply at the same time c:
a * m(b) *c <= c * b * m(a) + a * c - b * c
② The left and right sides of the formula are reduced at the same time b, Multiply at the same time a:
a * b * m(c) + a * c - b * a <= c * m(b) * a
Available
a * b * m(c) + a * c - b * a <= c * b * m(a) + a * c - b * c
Simultaneous subtraction (a * c ), obtain
a * b * m(c) - b*a <= c * b * m(a) - b * c
It also contains factors b, Divide both sides at the same time b:
a * m(c) - a <= c * m(a) - c
Move a and c:
a * m(c) +c <= c * m(a) + a
Turned intoa.c <= c.a
, End of proof .Prove that the resulting string must be the least lexicographically ordered .
First prove any 2 String if the exchange order , The dictionary order will only get bigger . And then whatever 3 individual , arbitrarily 4 individual , arbitrarily 5 individual ,…
Now we need to prove [… a m 1 m_1 m1 m 2 m_2 m2 b …] <= [… b m 1 m_1 m1 m 2 m_2 m2 a …]
First , If it's just exchange a and m 1 m_1 m1, Then according to Transitivity ,a. m 1 m_1 m1 <= m 1 m1 m1.a, therefore [… a m 1 m_1 m1 m 2 m_2 m2 b …] <= [… m 1 m_1 m1 a m 2 m_2 m2 b …]
Empathy , Again because a. m 2 m_2 m2 <= m 2 m_2 m2.a, therefore [… m 1 m_1 m1 a m 2 m_2 m2 b …] <= [… m 1 m_1 m1 m 2 m_2 m2 a b …]
Empathy , In exchange for a and b,[… m 1 m_1 m1 m 2 m_2 m2 a b …] <= [… m 1 m_1 m1 m 2 m_2 m2 b a …]
then b and m 2 m_2 m2 In exchange for ,[… m 1 m_1 m1 m 2 m_2 m2 b a …] <= [… m 1 m_1 m1 b m 2 m_2 m2 a …]
Last , In exchange for b and m 1 m_1 m1, So get [… m 1 m_1 m1 b m 2 m_2 m2 a …] <= […b m 1 m_1 m1 m 2 m_2 m2 a …]
In conclusion, it is : [… a m 1 m_1 m1 m 2 m_2 m2 b …] <= [… b m 1 m_1 m1 m 2 m_2 m2 a …].
So exchange a and b The order of , The dictionary order will only increase , It doesn't get smaller . Then prove that the exchange is arbitrary 3 individual 、4 individual 、… wait , It is deduced by mathematical induction .
however , In fact, the greedy strategy can know its correctness without proof . methodology : use Violent solution + Logarithmic apparatus To verify the correctness of the greedy strategy .
3、 Code implementation
C++ edition
/************************************************************************* > File Name: 034. The concatenated string dictionary order is the smallest .cpp > Author: Maureen > Mail: [email protected] > Created Time: Four 6/30 21:19:41 2022 ************************************************************************/
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <ctime>
using namespace std;
vector<string> removeIndexString(vector<string> &strs, int index) {
int n = strs.size();
vector<string> ans(n - 1);
int ansIndex = 0;
for (int i = 0; i < n; i++) {
if (i != index) {
ans[ansIndex++] = strs[i];
}
}
return ans;
}
set<string> process(vector<string> &strs) {
set<string> ans;
if (strs.size() == 0) {
ans.insert("");
return ans;
}
for (int i = 0; i < strs.size(); i++) {
string first = strs[i];
vector<string> nexts = removeIndexString(strs, i);
set<string> next = process(nexts);
for (string cur : next) {
ans.insert(first + cur);
}
}
return ans;
}
string lowestString1(vector<string> &strs) {
if (strs.size() == 0) return "";
set<string> ans = process(strs);
auto it = ans.begin();
return ans.size() == 0 ? "" : *it;
}
// Method 2 :
bool comp(const string &a, const string &b) {
return a + b < b + a;
}
string lowestString2(vector<string> &strs) {
if (strs.size() == 0) return "";
sort(strs.begin(), strs.end(), comp);
string res = "";
for (int i = 0; i < strs.size(); i++) {
res += strs[i];
}
return res;
}
//for test
string generateRandomString(int len) {
char *ans = new char[rand() % len + 1];
for (int i = 0; i < strlen(ans); i++) {
int value = rand() % 5;
ans[i] = (rand() % 100 / (double)101) <= 0.5 ? (char)(65 + value) : (char)(97 + value);
}
return ans;
}
vector<string> generateRandomStringArray(int alen, int slen) {
vector<string> ans(rand() % alen + 1);
for (int i = 0; i < ans.size(); i++) {
ans[i] = generateRandomString(slen);
}
return ans;
}
vector<string> copyStringArray(vector<string> &arr) {
vector<string> ans(arr.size());
for (int i = 0; i < ans.size(); i++) {
ans[i] = arr[i];
}
return ans;
}
int main() {
srand(time(0));
int arrLen = 6;
int strLen = 5;
int testTime = 10001;
cout << "test begin" << endl;
for (int i = 0; i < testTime; i++) {
vector<string> arr1 = generateRandomStringArray(arrLen, strLen);
vector<string> arr2 = copyStringArray(arr1);
if (lowestString1(arr1) != lowestString2(arr2)) {
for (string str : arr1) {
cout << str << " , ";
}
cout << endl;
cout << "Oops!" << endl;
break;
}
if (i && i % 100 == 0) cout << i << " cases passed!" << endl;
}
cout << "finish!" << endl;
return 0;
}
Java edition
package class13;
import java.util.Arrays;
import java.util.Comparator;
import java.util.TreeSet;
public class Code05_LowestLexicography {
// Method 1 : Violent solution
public static String lowestString1(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
TreeSet<String> ans = process(strs);
return ans.size() == 0 ? "" : ans.first();
}
// strs All strings in the are arranged completely , Returns all possible results
public static TreeSet<String> process(String[] strs) {
TreeSet<String> ans = new TreeSet<>();
if (strs.length == 0) {
ans.add("");
return ans;
}
for (int i = 0; i < strs.length; i++) {
String first = strs[i];
String[] nexts = removeIndexString(strs, i);
TreeSet<String> next = process(nexts);
for (String cur : next) {
ans.add(first + cur);
}
}
return ans;
}
// {"abc", "cks", "bct"}
// 0 1 2
// removeIndexString(arr , 1) -> {"abc", "bct"}
public static String[] removeIndexString(String[] arr, int index) {
int N = arr.length;
String[] ans = new String[N - 1];
int ansIndex = 0;
for (int i = 0; i < N; i++) {
if (i != index) {
ans[ansIndex++] = arr[i];
}
}
return ans;
}
// Method 2 : Use logarithm
public static class MyComparator implements Comparator<String> {
@Override
public int compare(String a, String b) {
return (a + b).compareTo(b + a);
}
}
public static String lowestString2(String[] strs) {
if (strs == null || strs.length == 0) {
return "";
}
Arrays.sort(strs, new MyComparator());
String res = "";
for (int i = 0; i < strs.length; i++) {
res += strs[i];
}
return res;
}
// for test
public static String generateRandomString(int strLen) {
char[] ans = new char[(int) (Math.random() * strLen) + 1];
for (int i = 0; i < ans.length; i++) {
int value = (int) (Math.random() * 5);
ans[i] = (Math.random() <= 0.5) ? (char) (65 + value) : (char) (97 + value);
}
return String.valueOf(ans);
}
// for test
public static String[] generateRandomStringArray(int arrLen, int strLen) {
String[] ans = new String[(int) (Math.random() * arrLen) + 1];
for (int i = 0; i < ans.length; i++) {
ans[i] = generateRandomString(strLen);
}
return ans;
}
// for test
public static String[] copyStringArray(String[] arr) {
String[] ans = new String[arr.length];
for (int i = 0; i < ans.length; i++) {
ans[i] = String.valueOf(arr[i]);
}
return ans;
}
public static void main(String[] args) {
int arrLen = 6;
int strLen = 5;
int testTimes = 10000;
System.out.println("test begin");
for (int i = 0; i < testTimes; i++) {
String[] arr1 = generateRandomStringArray(arrLen, strLen);
String[] arr2 = copyStringArray(arr1);
if (!lowestString1(arr1).equals(lowestString2(arr2))) {
for (String str : arr1) {
System.out.print(str + ",");
}
System.out.println();
System.out.println("Oops!");
}
}
System.out.println("finish!");
}
}
边栏推荐
- Red team Chapter 10: ColdFusion the difficult process of deserializing WAF to exp to get the target
- 芯片供应转向过剩,中国芯片日产增加至10亿,国外芯片将更难受
- Detailed explanation of activity life cycle and startup mode
- China benzene hydrogenation Market Research and investment forecast report (2022 Edition)
- What are the differences between PHP and DW
- Sword finger offer II 015 All modifiers in the string
- P2893 [USACO08FEB] Making the Grade G(dp&优先队列)
- 阿里云、追一科技抢滩对话式AI
- 程序员职业生涯真的很短吗?
- Introduction to software engineering - Chapter 6 - detailed design
猜你喜欢
数据库系统原理与应用教程(001)—— MySQL 安装与配置:MySQL 软件的安装(windows 环境)
Comment utiliser le langage MySQL pour les appareils de ligne et de ligne?
Tutorial on principles and applications of database system (004) -- MySQL installation and configuration: resetting MySQL login password (Windows Environment)
Detailed explanation of activity life cycle and startup mode
Introduction to software engineering - Chapter 6 - detailed design
模板引擎Velocity 基础
Tutorial on the principle and application of database system (001) -- MySQL installation and configuration: installation of MySQL software (Windows Environment)
C language input / output stream and file operation
What is the digital transformation of manufacturing industry
[flask introduction series] cookies and session
随机推荐
Buuctf gold III
Hi Fun Summer, play SQL planner with starrocks!
Is the securities account given by the head teacher of goucai school safe? Can I open an account?
广东用电量大跌,说明高新技术产业替代高能耗产业已取得初步成果
String类
Building blocks for domestic databases, stonedb integrated real-time HTAP database is officially open source!
C语言输入/输出流和文件操作
China's intelligent transportation construction from the perspective of "one hour life circle" in Dawan District
How to solve the keyboard key failure of notebook computer
數據庫系統原理與應用教程(006)—— 編譯安裝 MySQL5.7(Linux 環境)
独家消息:阿里云悄然推出RPA云电脑,已与多家RPA厂商开放合作
[nodemon] app crashed - waiting for file changes before starting...解决方法
Origin2018 installation and use (sorting)
How does go use symmetric encryption?
VMware 虚拟机启动时出现故障:VMware Workstation 与 Hyper-v 不兼容...
China carbon disulfide industry research and investment strategy report (2022 Edition)
Installation and use of sqoop
免费抽奖 | 《阿巴豆》探索未来系列盲盒数字版权作品全网首发!
Go language source level debugger delve
Kali install Nessus