第一次写题解,因为这题实在是有点难为我这个初学者了。本人很菜对字符串处理更是不怎么行。所以写这篇题解来 理一下思路。
重点!!PTA不支持gets_s函数,只能在VS里用这个,PTA改成gets就行!!
有什么地方不对,还请指出,谢谢。
题目
小明看到课表上某课程的上课周次是这样标示的:1, 8,12-17,3-6 。请你编写程序,将从输入设备上输入的如前述类似的周次表示字符串,转换成标准的周次表示。
输入格式:
一个数字表示某一周,两个数字中间以-号分隔的表示某周次区间,a-b表示 区间[a,b],程序确保a<b,但不能够确保周次间是升序排列的。所有的周次在【1,20】内。
输入有若干行,每行一个课程的上课周次。
输出格式:
从小到大的顺序输出有课程的周次,周与周间以逗号分隔,最后没有逗号。
输入样例:
3-5,8,13-15,17,10-12
13-18,5-9
3-13 , 13 - 17
输出样例:
3,4,5,8,10,11,12,13,14,15,17
5,6,7,8,9,13,14,15,16,17,18
3,4,5,6,7,8,9,10,11,12,13,14,15,16,17
先来给大家排几个让我挺难受的坑。
1.gets函数是不读入回车的,以'\0'结尾。
2.对于12-17这种有两位数的,需要先判断,改写成数字再处理。(肯定有更好的办法的,只是我想不到。)
3.如果是1-3,3-4需要判断3输出的次数,不能输出两次3。
整体思路
首先把所有的二位数和空格处理好,二位字符改成数字,空格删去。
int j=0;
for (int i = 0, a = 0;; i++)
{
if (str[i] >= '1' && str[i] <= '9' && str[i + 1] >= '0' && str[i + 1] <= '9')
str[a++] = (str[i] - '0') * 10 + (str[i + 1] - '0'), i++;//把二位数改成数字
else if (str[i] >= '1' && str[i] <= '9')//把字符改成数字
str[a++] = str[i] - '0';
else if (str[i] != ' ')str[a++] = str[i];//处理空格
if (str[i] == '\0')
break;
}
然后判断 ' - ' 号,遇到 ' - ' 号则,判断减号前后是否为数字,如果是就展开。这步还是很简单的。
if (str[i] == '-')
{
for (int k = str[i - 1] + 1; k < str[i + 1]; k++)
{
str1[j++] = k;
}
i++;
}
除了减号之外的数字都存起来。这里有一个坑,数字现在最大是20而不是9了。
else
{
if (str[i] >= 1 && str[i] <= 20)
str1[j++] = str[i++];
else i++;
}
再排序,输出就行。
接下来是大家最喜欢的环节。(bushi)
#include <stdio.h>
#include <string.h>
char str[1000];
char str1[1000];
void sort(char* str, int n)//最简单的排序,大家都会写。
{
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
{
int tem;
if (str[i] > str[j])
{
tem = str[i];
str[i] = str[j];
str[j] = tem;
}
}
}
}
int main()
{
while (gets_s(str) != NULL)//VS里不能用gets,所以只能用gest_s了,但是PTA提交只能用gets函数!!
{
int i = 0;//读取数组的下标
int j = 0;//最终数组的下标
for (int i = 0, a = 0;; i++)
{
if (str[i] >= '1' && str[i] <= '9' && str[i + 1] >= '0' && str[i + 1] <= '9')
str[a++] = (str[i] - '0') * 10 + (str[i + 1] - '0'), i++;
else if (str[i] >= '1' && str[i] <= '9')
str[a++] = str[i] - '0';
else if (str[i] != ' ')str[a++] = str[i];
if (str[i] == '\0')
break;
}
while (str[i] != '\0')
{
if (str[i] == '-')
{
for (int k = str[i - 1] + 1; k < str[i + 1]; k++)
{
str1[j++] = k;
}
i++;
}
else
{
if (str[i] >= 1 && str[i] <= 20)
str1[j++] = str[i++];
else i++;
}
}
sort(str1, j);
for (int i = 0, j = 0;; i++)
{
if (str1[i] == '\0')
{
str1[j] = str1[i];
break;
}
if (str1[i] != str1[i + 1])
str1[j++] = str1[i];
}//这里我用了最笨的办法,去判断重复元素,其实可以用桶排快速解决的。
for (int k = 0;; k++)
{
if (str1[k] == '\0')
{
break;
}
k == 0 ? printf("") : printf(",");
printf("%d", str1[k]);
}
printf("\n");//每行最后记得换行
i = 0;
j = 0;
for (int i = 0;; i++)//重置目标数组
{
if (str1[i] == '\0')
break;
str1[i] = '\0';
}
}
return 0;
}