首先看一下题
描述
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
数据范围:输入的字符串长度满足 1≤n≤1000
输入描述:
输入字符串
输出描述:
输出字符串
示例1
输入:
A Famous Saying: Much Ado About Nothing (2012/8).输出:
A aaAAbc dFgghh: iimM nNn oooos Sttuuuy (2012/8).
一、问题分析
题目的要求是:
1.编写一个程序,将输入字符串中的字符按一定的规则排列
2.规则1:英文字母从A到Z排列,不区分大小写
3.规则2:同一个英文字母的大小写同时存在的时候,按照输入顺序排列
4.规则3:非英文字母的其它字符保持原来的位置
5.数据范围:输入的字符串长度满足:n大于等于1小于等于1000
6.输入描述:输入字符串
7.输出描述:输出字符串
二、解题思路
1.我们需要重新排列一个字符串,按照字母顺序排列,非字母的其它字符的位置固定不变
2.我们需要注意的是,字母的大小写形式同时存在时,在前面的还是在前面,后面的还是在后面
3.我们可以遍历字符串,从A到Z搜索,如果遇到A,就把A和前面的非A的字母顺序调换,直到字符串末尾
4.我们可以定义一个开始的位置startIndex = 0,每次我们交换了一个字母的顺序到前面,或者我们遇到了我们正要搜索的字母或者我们碰到了非字母的字符我们直接startIndex++, 下次我们只需要从startIndex的位置向后遍历就可以了
比如例子里这个字符串
A Famous Saying: Much Ado About Nothing (2012/8).
我们搜索A,发现了A, 我们直接startIndex++;(现在是1)
然后我们继续搜索A,搜索到了第四个位置的a,我们尝试和前面的字符交换,
由于之前startIndex增加了1,变成了1,所以现在在空格的位置,
我们判断出来是一个空格,于是我们startIndex++(现在是2),然后继续往后找
发现了字母F,我们a和F的顺序调换,
于是字符串变成了
A aFmous Saying: Much Ado About Nothing (2012/8).
之后我们startIndex++,(此时的startIndex在3的位置,也就是F的位置)
然后继续往后找,又找到一个a,然后和F的位置交换字符串变成了
A aamous SFying: Much Ado About Nothing (2012/8).
然后startIndex++,这样的逻辑应该可以完成我们的要求
5.还有一点需要注意,我们不希望写26次判断语句,所以我们可以用ASCII码的方式对字母进行判断
if(input[j] == 'a' + i || input[j] == 'A' + i)
3.按照刚才的说法忽略了规则2,正确的做法应该是定义一个新的char newstr[1001];
然后定义一个int index = 0;用来辅助创建newstr
定义一个int len = strlen(str);
对于i=0-26,遍历26个字母
对于str[j],j=0到len遍历字符串,如果遇到了str[j] == 'a' + i || str[j] == 'A' + i的情况(遇到目标字母)
我们检查isalpha(str[index]),如果str[index]是字母,那么我们newstr[index] = str[j]
否则我们newstr[index]=str[index]
然后index++
之后打印newstr就可以了
三、具体步骤
使用的语言是C
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char str[1001];
fgets(str, sizeof(str), stdin);
int startIndex = 0;
int endIndex = strlen(str);
// printf("the endindex is %d\n", endIndex);
if(endIndex == 0) return 0;
for(int i = endIndex; i > 0; i--) {
if(isalpha(str[i])) {
endIndex = i;
break;
}
}
// printf("the endindex is %d\n", endIndex);
// printf("the character here is %c\n", str[endIndex]);
for(int i = 0; i < 26; i++) {
for(int j = startIndex; j <= endIndex; j++) {
if(str[j] == 'a' + i || str[j] == 'A' + i) { //如果碰到了要找的字母(需要放到前面的字母)
// printf("the i is %d\nthe j is %d\n",i ,j);
if(j == startIndex) {
// printf("in this situation the current character is our target.\n");
startIndex++;
}else {
// 我们需要去寻找可以和我们的要放到前面的字母交换位置的字母
for(int k = startIndex; k <= j; k++) {
if(!isalpha(str[k])) {
startIndex++;
// printf("the startindex is %d now\n", startIndex);
} else {
char temp = str[k];
str[k] = str[j];
str[j] = temp;
startIndex++;
break;
}
}
}
}
}
}
// str[strlen(str)] = '\0';
printf("%s\n", str);
return 0;
}
下面是正确的代码
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
char str[1001];
fgets(str, sizeof(str), stdin);
char newstr[1001];
int len = strlen(str);
int newstrIndex = 0;
int strIndex = 0;
for(int i = 0; i < 26; i++) {
for(int j = 0; j < len; j++) {
while(!isalpha(str[newstrIndex]) && newstrIndex < len) {
newstr[newstrIndex] = str[newstrIndex];
newstrIndex++;
}
if(str[j] == 'a' + i || str[j] == 'A' + i) {
newstr[newstrIndex] = str[j];
newstrIndex++;
}
}
}
newstr[newstrIndex] = '\0';
printf("%s\n", newstr);
return 0;
}
20241031 22:00-2041101 11:31