文件压缩【字符串】

提高文件的压缩率一直是人们追求的目标。近几年有人提出了这样一种算法,它虽然只是单纯地对文件进行重排,本身并不压缩文件,但是经这种算法调整后的文件在大多数情况下都能获得比原来更大的压缩率。 该算法具体如下:对一个长度为n的字符串S,首先根据它构造n个字符串,其中第i个字符串由将S的前i-1个字符置于末尾得到。然后把这n个字符串按照首字符从小到大排序,如果两个字符串的首字符相等,则按照它们在S中的位置从小到大排序。排序后的字符串的尾字符可以组成一个新的字符串S’,它的长度也是n,并且包含了S中的每一个字符。最后输出S’以及S的首字符在S’中的位置p。

举例: S: example

1、构造n个字符串 example xamplee ampleex mpleexa pleexam leexamp eexampl

2、将字符串排序 ampleex example eexampl leexamp mpleexa pleexam xamplee

3、压缩结果 S’= xelpame ,p=7

由于英语单词构造的特殊性,某些字母对出现的频率很高,因此在S’中相同的字母有很大几率排在一起,从而提高S’的压缩率。虽然这种算法利用了英语单词的特性,然而在实践的过程中,人们发现它几乎适用于所有的文件压缩。

请你编一个程序,读入S’和p,输出字符串S。


如题意:"①按首字符从小到大排序,若两字符串首字符相等,②则按其

在S中位置从小到大排序。"

依①,必得首字符递增序列,设其为c。

故此序列可由所给字符串s排序得,且与s首尾一一对应。

这种首尾关系,体现在原序列上是相邻。

即s内字符在原序列中是c内字符前一位。

故当确定一字符位置,可推其余字符位置。

现在暴力分析:

由于②,该排序方式体现在c上,原序列一定有重复字母。

所以只能由c推,所以只能从后往前推(c->s)。

已知第一字符,由于其位置第一,在c中必为相等字符之首。

由此,线性推。
int main() {
	ll n, p; string s;
	while (cin >> n >> s >> p) {
		string t = s, res;
		sort(t.begin(), t.end());
		p = t.find(s[p - 1]);//p-1号是相同元素中最靠前的
		while (res.size() < n) {
			ll id = -1;
			//s[p]肯定是t中后出现的元素 因为倒推
			for (int j = n - 1; j >= 0; j--)if (t[j] == s[p]) { id = j; break; }
			res += t[id]; t[id] = ' '; p = id;
		}
		reverse(res.begin(), res.end());
		cout << res << endl;
	}
}

你可能感兴趣的:(牛客网&LuoGu练习题,ACM字符串问题)