信息学奥赛一本通 2048:【例5.18】串排序

本文介绍了C++中处理字符串排序的三种方法,包括使用string类对象数组、二维数组和指针数组,并展示了每种方法的代码实现。此外,还提到了字符串比较的基本原则和内置函数的使用,如strcmp和string类的比较操作符。通过选择排序、冒泡排序和sort函数等排序算法,实现了字符串的升序排列。
摘要由CSDN通过智能技术生成

【题目链接】

ybt 2048:【例5.18】串排序

【题目考点】

1. 多字符串处理
  • 方法1:string类对象数组
    设string类对象数组s,s[i]保存第i个字符串。s[i]是string类对象。
string s[105];//s[i]保存第i个字符串
int n;
cin >> n;
for(int i = 1; i <= n; ++i)
	cin >> s[i];
  • 方法2:二维数组
    设二维数组s,s[i]保存第i个字符串。s[i]是char*类型指针常量,是一维字符数组。缺点是指针不可改变。
    例:输入n,输入n个字符串
char s[105][105];//s[i]保存第i个字符串
int n;
cin >> n;
for(int i = 1; i <= n; ++i)
	cin >> s[i];
  • 方法3:指针数组
    设指针数组s,s[i]保存第i个字符串。s[i]是char*类型指针变量,指向一维字符数组。
    使用前需要动态申请内存空间。优点是指针值可以改变。
char *s[105];//s[i]保存第i个字符串
int n;
cin >> n;
for(int i = 1; i <= n; ++i)
{
	s[i] = new int[105];//申请完记得释放
	cin >> s[i];
}
2. 排序

本题考查重点不是排序,随便选一种基本排序方法就好,或者用sort函数进行排序。
sort函数使用可以读者自行搜索。这里不做过多介绍。

3. 字符串比较

基于字典序比较:遍历两个字符串,对应位置字符进行比较

  • 如果发现字符不同,哪个字符的ASCII码大,那个字符所在的字符串就更大
  • 如果字符相同,看下一个字符
  • 如果一个字符串遍历完了,另一个字符串没遍历完,那么更长的字符串更大。
  • 如果两个字符串同时遍历完,那么两字符串相同

字符数组比较:strcmp(s1, s2),其中s1, s2是字符数组

  • 如果s1比s2小,即s1字典序在s2前,返回 -1
  • 如果s1比s2大,即s1字典序在s2后面,返回1
  • 如果s1与s2相同,返回0

string类对象比较:>, <, >=, <=, ==, !=
string类对象重载了各种关系运算符,可以用关系运算符直接比较

【解题思路】

存储结构可以选择:string类数组,指针数组,二维数组
排序方法可以有多种选择,大体分为:手写排序、调用stl排序函数(如sort函数)
以下给出几种方法示例

【题解代码】

解法1:string类+sort函数
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s[25];//string类数组 
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i)
        cin >> s[i];
    sort(s+1, s+1+n);//默认升序 比较时使用string类重载的<运算符 
    for(int i = 1; i <= n; ++i)
        cout << s[i] << endl;
    return 0;
}
解法2:string类数组+选择排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s[25];
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i)
        cin >> s[i];
    for(int i = 1; i <= n - 1; ++i)//选择排序
    {
        int m = i;//找从i+1~n最小值下标 
        for(int j = i + 1; j <= n; ++j)
        {
            if(s[j] < s[m])
                m = j;
        }
        swap(s[m], s[i]);
    }
    for(int i = 1; i <= n; ++i)
        cout << s[i] << endl;
    return 0;
}
解法3:指针数组+冒泡排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char *s[25];//指针数组 
    int n;
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        s[i] = new char[25];//动态内存申请 
        cin >> s[i];
    }
    for(int i = 1; i <= n-1; ++i)
        for(int j = 1; j <= n-i; ++j)
        {
            if(strcmp(s[j], s[j+1]) > 0)//或写为==1 
                swap(s[j], s[j+1]);//s[j]和s[j+1]是char*类型指针变量,可以交换    
        }
    for(int i = 1; i <= n; ++i)
    {
        cout << s[i] << endl; 
        delete s[i];//动态申请的内存要释放,虽然程序运行完了也能释放,但要养成这种手动释放的习惯。以防工作后写出使内存泄露的程序。 
    }
    return 0;
}
解法4:二维数组+索引数组+插入排序
#include<bits/stdc++.h>
using namespace std;
int main()
{
    char s[25][25]; 
    int n, ind[25];//s[ind[i]]:索引数组,排序后第i个元素 
    cin >> n;
    for(int i = 1; i <= n; ++i)
    {
        cin >> s[i];
        ind[i] = i;
    }
    for(int i = 2; i <= n; ++i)//把第几个元素插入有序序列 
        for(int j = i; j >= 2; --j)
        {
            if(strcmp(s[ind[j]], s[ind[j-1]]) < 0)//排序后数组第j元素小于排序后第j-1元素 
                swap(ind[j], ind[j-1]);
            else
                break;
        }
    for(int i = 1; i <= n; ++i)
        cout << s[ind[i]] << endl;
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值