string数组的字典序排列 C++



#include <iostream>
#include <string>
#include<vector>
#include<algorithm>
using namespace std;

template<typename T >
void fun(T val)
{
	cout << val << endl;
}
bool cmp(string s1, string s2)
{
	int n1 = s1.size();
	int n2 = s2.size();
	int n = min(n1, n2);

	//逐位比较字典序
	for (int i = 0; i < n; i++)
	{
		char c1 = s1[i];
		char c2 = s2[i];
		if (c1 == c2)
			continue;
		else if (c1 < c2)
			return true;   //s1字典序更小
		else
			return false;  //s2字典序更小,交换位置
	}
	//到这一步说明两个字符串前n位相同,比较字符串长度
	return n1 < n2;
	//n1<n2时不用交换位置
	//n2<=n1时交换位置
}
int main()
{
	vector<string> vec = { "abcdf","aaaer","bcda","qweqeqeqe","ab","a","b" };
	//1方法
	cout << "------------cmp func------------" << endl;
	sort(vec.begin(), vec.end(), cmp);
	for_each(vec.begin(), vec.end(), fun<string>);

	//2方法
	cout << "------------operator<------------" << endl;
	sort(vec.begin(), vec.end(), [](const string& a, const string& b) {
		return a < b;     //string类中重载<号可以自动比较字典序大小
		});
	for_each(vec.begin(), vec.end(), fun<string>);

	//3方法
	cout << "------------string::compare------------" << endl;
	sort(vec.begin(), vec.end(), [](const string& a, const string& b) {
			return a.compare(b) < 0;     //相等返回0,a<b时返回-1,a>b时返回1;
		});
	for_each(vec.begin(), vec.end(), fun<string>);

	return 0;
}


测试结果
在这里插入图片描述

PS: string类中重载<号内部就是调用compare,下面是vs2019中的string源码

template <class _Elem, class _Traits, class _Alloc>
_NODISCARD bool operator<(
    const basic_string<_Elem, _Traits, _Alloc>& _Left, const basic_string<_Elem, _Traits, _Alloc>& _Right) noexcept {
    return _Left.compare(_Right) < 0;
}
以下是一个使用 C++ 实现的部分字典序排列代码,包含详细的注释: ``` #include <iostream> #include <algorithm> #include <cstring> using namespace std; int main() { // 读入字符串 string s; cin >> s; // 计算字符串长度 int n = s.length(); // 将字符串转换为字符数组,方便排序 char c[n + 1]; strcpy(c, s.c_str()); // 排序字符数组 sort(c, c + n); // 打印第一个排列 cout << c << endl; // 循环生成下一个排列,直到生成的排列等于原字符串 while (true) { // 从后往前找到第一个不满足逆序对条件的位置 int i = n - 2; while (i >= 0 && c[i] >= c[i + 1]) { i--; } // 如果找不到这样的位置,说明已经生成了所有排列,退出循环 if (i < 0) { break; } // 从后往前找到第一个大于 c[i] 的位置 int j = n - 1; while (j > i && c[j] <= c[i]) { j--; } // 交换 c[i] 和 c[j] swap(c[i], c[j]); // 反转 c[i+1] 到 c[n-1] 的所有元素 reverse(c + i + 1, c + n); // 打印生成的下一个排列 cout << c << endl; } return 0; } ``` 该代码先读入一个字符串,然后将其转换为字符数组并排序,打印第一个排列。接下来循环生成下一个排列,直到生成的排列等于原字符串。在每次生成下一个排列时,该代码从后往前找到第一个不满足逆序对条件的位置,从后往前找到第一个大于 c[i] 的位置,交换 c[i] 和 c[j],然后反转 c[i+1] 到 c[n-1] 的所有元素,最后打印生成的下一个排列
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值