Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 求满足给定顺序的唯一字符字典最小字符串的算法_String_Algorithm - Fatal编程技术网

String 求满足给定顺序的唯一字符字典最小字符串的算法

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处得到一个额外的“”,我们应

如何找到词典学上最小的字符串,并具有满足字符串形式中给定顺序的唯一字符,对于字符串长度N,用“>”和“填充字符串,形成一个具有N+1个节点和N条定向边的图,其中
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';
    }
}