String 求满足给定顺序的唯一字符字典最小字符串的算法
如何找到词典学上最小的字符串,并具有满足字符串形式中给定顺序的唯一字符,对于字符串长度N,用“>”和“填充字符串,形成一个具有N+1个节点和N条定向边的图,其中String 求满足给定顺序的唯一字符字典最小字符串的算法,string,algorithm,String,Algorithm,如何找到词典学上最小的字符串,并具有满足字符串形式中给定顺序的唯一字符,对于字符串长度N,用“>”和“填充字符串,形成一个具有N+1个节点和N条定向边的图,其中p[i]3 ^ / 4. 1 4 2 3//可能的拓扑顺序之一 1 2 4 3//在2/4互换后 | | | | 分配字母 a如果我理解正确,您的输入字符串将比预期的输出字符串少一个字符,因为每个字符描述两个连续字符之间的关系。而且您似乎还希望输出仅由小写拉丁字母组成 我将扩展该输入字符串,使其在位置k处得到一个额外的“”,我们应
p[i]
表示从第i个节点到第j个节点的边
然后对该图执行以下操作
对违反自然顺序且没有边的相邻对进行最小结果交换(请参见“唯一性”部分)
将字母表字符按排序顺序分配给节点
1<2<3>4
graph:
1 -> 2 -> 3
^
/
4
1 4 2 3 //one of the possible topologic orderings
1 2 4 3 //after 2/4 swap
| | | |
a b c d //assign letters
a<b<d>c
12->3
^
/
4.
1 4 2 3//可能的拓扑顺序之一
1 2 4 3//在2/4互换后
| | | |
分配字母
a如果我理解正确,您的输入字符串将比预期的输出字符串少一个字符,因为每个字符描述两个连续字符之间的关系。而且您似乎还希望输出仅由小写拉丁字母组成
我将扩展该输入字符串,使其在位置k处得到一个额外的“”,我们应该查找这一系列“>”的结尾,直到下一个“问题是用从0到n-1的数字填充数组,这样就可以考虑局部不平等性,并且尽可能将最小的数字定位在数组的开头
一个简单的解决方案是按相反的顺序读取输入字符串,首先尝试放置n-1,然后放置n-2等
遇到
>->cba
>>->edcba
>>->baedc
C++中的代码:
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <numeric>
std::string smallest_s (const std::string &s_in) {
int n = s_in.size() + 1;
std::string s;
s.resize(n);
std::vector<int> ans (n);
int index = n-1;
std::stack<int> qu;
qu.push (n-1);
for (int j = n-2; j >= 0; j--) {
if (s_in[j] == '<') {
while (!qu.empty()) {
ans[index--] = qu.top();
qu.pop();
}
}
qu.push (j);
}
while (!qu.empty()) {
ans[index--] = qu.top();
qu.pop();
}
for (int i = 0; i < n; ++i)
s[i] = 'a' + ans[i];
return s;
}
int main() {
for (const std::string &s_in: {">>", "<<<<", "<<><", ">>>>", "><>>"}) {
std::cout << s_in << " -> " << smallest_s(s_in) << '\n';
}
}
#包括
#包括
#包括
#包括
#包括
#包括
std::string最小值(const std::string&s_in){
int n=s_in.size()+1;
std::字符串s;
s、 调整大小(n);
std::向量ans(n);
int指数=n-1;
std::堆栈qu;
qu.push(n-1);
对于(int j=n-2;j>=0;j--){
如果(s_in[j]=',但我给出了示例。添加了图片。我得到这个直到拓扑排序。所以如果有多个排序可能-其中一个是答案?如果是,如何确定正确的排序?是的,我们可以得到任意拓扑排序,然后按字典顺序进行最小排序-这就是答案。
>> -> cba
<<<< -> abcde
<<>< -> abdce
>>>> -> edcba
><>> -> baedc
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <numeric>
std::string smallest_s (const std::string &s_in) {
int n = s_in.size() + 1;
std::string s;
s.resize(n);
std::vector<int> ans (n);
int index = n-1;
std::stack<int> qu;
qu.push (n-1);
for (int j = n-2; j >= 0; j--) {
if (s_in[j] == '<') {
while (!qu.empty()) {
ans[index--] = qu.top();
qu.pop();
}
}
qu.push (j);
}
while (!qu.empty()) {
ans[index--] = qu.top();
qu.pop();
}
for (int i = 0; i < n; ++i)
s[i] = 'a' + ans[i];
return s;
}
int main() {
for (const std::string &s_in: {">>", "<<<<", "<<><", ">>>>", "><>>"}) {
std::cout << s_in << " -> " << smallest_s(s_in) << '\n';
}
}