北大的题可真难啊!!!
我想了一个小时!!!T_T
题目描述
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
样例:
输入:
A Famous Saying: Much Ado About Nothing(2012/8).
输出:
A aaAAbc dFgghh : iimM nNn oooos Sttuuuy (2012/8).
示例1
输入
A Famous Saying: Much Ado About Nothing (2012/8).
输出
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
#include <bits/stdc++.h>
#include <cstdio>
#include <stdio.h>
using namespace std;
struct st//结构体数组,包括内容和下标
{
char ch;
int loc;
}y[100],qt[100];//y结构体数组表示字符,qt表示其他
bool cmp(struct st a,struct st b)//比较函数
{
/*先将参数统一,不分大小写*/
if(a.ch>='A'&&a.ch<='Z')
a.ch-='A';
if(a.ch>='a'&&a.ch<='z')
a.ch-='a';
if(b.ch>='A'&&b.ch<='Z')
b.ch-='A';
if(b.ch>='a'&&b.ch<='z')
b.ch-='a';
//如果不等就升序
if(a.ch!=b.ch)
return bool(a.ch<b.ch);
//否则按输入顺序升序
return bool(a.loc<b.loc);
}
int main()
{
int i,j,k,index,last_index;//i是循环变量,j和k分别是两个结构体数组的移动下标,index是每次插入的非字母的下标,last_index表示每次插完后最后一个字符的下标
char s[100];
while(gets(s)!=NULL)
{
j=k=0;
for(i=0;s[i]!='\0';i++)//从头到尾扫描
if(s[i]>='a'&&s[i]<='z'||s[i]>='A'&&s[i]<='Z')//发现字母,更新y
{
y[j].ch=s[i];
y[j++].loc=i;
}
else//发现其他,更新qt
{
qt[k].ch=s[i];
qt[k++].loc=i;
}
last_index=j-1;//因为刚才j最后++了一下,因此最后一个字符实际是j-1
sort(y,y+j,cmp);//快排一下
for(i=0;i<k;i++)//现在对qt进行查找,把每个其他字符插进去,同时移动
{
index=qt[i].loc;//先锁定下标
for(j=last_index;j>=index;j--)//开始大量移动
y[j+1].ch=y[j].ch;
y[index].ch=qt[i].ch;//填进去
last_index++;//同时最后一个字符的下标++(因为多加了一个)
}
for(i=0;i<=last_index;i++)//从头到last_index遍历即可
cout<<y[i].ch;
cout<<endl;
}
}
