华为机试HJ17 坐标移动
首先看一下题
描述
开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从(0,0)点开始移动,从输入字符串里面读取一些坐标,并将最终输入结果输出到输出文件里面。
输入:
合法坐标为A(或者D或者W或者S) + 数字(两位以内)
坐标之间以;分隔。
非法坐标点需要进行丢弃。如AA10; A1A; $%$; YAD; 等。
下面是一个简单的例子 如:
A10;S20;W10;D30;X;A1A;B10A11;;A10;
处理过程:
起点(0,0)
+ A10 = (-10,0)
+ S20 = (-10,-20)
+ W10 = (-10,-10)
+ D30 = (20,-10)
+ x = 无效
+ A1A = 无效
+ B10A11 = 无效
+ 一个空 不影响
+ A10 = (10,-10)
结果 (10, -10)
数据范围:每组输入的字符串长度满足 1≤n≤10000 ,坐标保证满足 −2^31≤x,y≤2^31−1 ,且数字部分仅含正数
输入描述:
一行字符串
输出描述:
最终坐标,以逗号分隔
示例1
输入:
A10;S20;W10;D30;X;A1A;B10A11;;A10;输出:
10,-10示例2
输入:
ABC;AKL;DA1;输出:
0,0
一、问题分析
1.开发一个坐标计算工具
2.A表示向左移动
3.D表示向右移动
4.W表示向上移动
5.S表示向下移动
6.从(0,0)点开始移动
7.从输入字符串里读取一些坐标
8.将最终输入结果输出到输出文件里面
9.合法坐标为A(或者D或者W或者S) + 数字(两位以内)
10.坐标之间以;分隔
11.非法坐标点需要进行丢弃。如AA10; A1A; $%$; YAD; 等。
从例子中可以看出,丢弃非法坐标时,只丢弃本组非法坐标(以;为结尾)
;之后的坐标如果是合法坐标不丢弃
12.数据范围:每组输入的字符串长度大于等于1,小于等于10000
13.坐标的x和y值满足大于等于-2^31,小于等于2^31-1,且数字部分仅含正数
14.输入描述:一行字符串
15.输出描述:最终坐标,以逗号分隔
二、解题思路
1.首先我们确定我们的坐标原点是(0,0)
2.我们需要选择一种方式存储我们的坐标,这里直接定义两个整数x=0,y=0来代表x坐标和y坐标值
3.我们需要对输入字符串进行处理
4.首先我们定义一个char input[10000];用来存储我们的输入字符串
5.然后我们将输入scanf到input中
6.我们定义我们的x和y并给他们赋一个初始值0(坐标原点0,0)
7.我们需要对每个“;”分隔开的字符串做验证,如果符合一个方向字母(A|S|D|W)+1或者2位数字的我们进行坐标移动,不符合的我们丢弃该字符串
8.我们可以使用<string.h>中的strtor函数对字符串进行处理
9.使用方式是strtor(要分割的字符串,分隔字符串)
10.我们需要char *token = strtor(input, ";");定义一个token指针用来存储我们strtor分隔出来的子字符串
11.我们开始遍历token(每一个以;结尾的字符串)
遍历条件是while(token != NULL), 每次循环结束的部分我们token = strtor(NULL, ";");读取下一个;结尾的字符串
12.然后我们定义一个int len = strlen(token);用来储存我们当前字符串的长度
13.因为我们的有效坐标是方向加最多两位数字,所以一共有两种情况
一种是方向加一位数字,一种是方向加两位数字,所以只有字符串长度为2或者3的时候才是有效输入
14.所以我们len<4的时候才是有效输入,我们加一个if语句将大于等于4的字符串剔除
15.然后我们需要储存方向char direction = token[0];
为什么不直接移动呢?因为当我们判断完方向之后还需要判断移动的步数
如果直接先判断方向再判断步数,我们需要写四次步数判断,但是如果我们先将方向和步数都读取到我们的变量中那么就不用写四次步数判断了
16.然后我们定义一个变量int num = 0;用来存储我们的步数
17.我们int valid = 1;用来应对如果出现后两位不是数字的情况将valid变成0
18.我们判断如果len是3并且字符串的第二位token[1]是一个数字的时候
这个时候我们需要<ctype.h>库的isdigit函数isdigit(需要判断的字符)会返回是如果是数字,返回否如果不是数字
这个时候我们的num变成token[1]的值num = token[1] - '0';
然后我们继续判断if(isdigit(token[2]))如果第三位也是数字那么我们
num = num * 10 + token[2] - '0';
如果我们第三位不是数字,我们将valid变成0
19.如果我们len是2并且token[1]是数字那么我们的num = token[1] - '0';
20.其他的所有情况我们的valid = 0;
21.对于direction是'A','W','S','D',并且valid = 1的情况我们是有正常坐标输入的我们予以处理
22.如果direction == 'A'我们x -= num;如果direction == 'D'我们x += num;如果direction == 'W'我们y += num;如果direction == 'S';我们y -= num;
23.别忘了进入下一个以‘;’结尾的坐标token = strtok(NULL,';');
24.输出我们的坐标
三、具体步骤
使用的语言是C
#include <stdio.h>
#include <string.h>
#include <ctype.h>int main() {char input[10000];scanf("%s", input);int x = 0, y = 0;char* token = strtok(input, ";");while (token!= NULL) {int len = strlen(token);if(len < 4){char direction = token[0];int num = 0;int valid = 1;if (len == 3 && isdigit(token[1])) {num = token[1] - '0';if (isdigit(token[2])) {num = num * 10 + token[2] - '0';} else if(!isdigit(token[2])){valid = 0;}} else if(len == 2 && isdigit(token[1])){num = token[1] - '0';} else {valid = 0;}if ((direction == 'A' || direction == 'D' || direction == 'W' || direction == 'S') && valid) {if (direction == 'A') {x -= num;} else if (direction == 'D') {x += num;} else if (direction == 'W') {y += num;} else if (direction == 'S') {y -= num;}}}token = strtok(NULL, ";");}printf("%d,%d\n", x, y);return 0;
}
重新整理了一下
#include <stdio.h>
#include <string.h>
#include <ctype.h>int main(){char input[10000];scanf("%s", input);int x = 0, y = 0;char* token = strtok(input, ";");while(token != NULL){int len = strlen(token);char direction = token[0];int num = 0;int valid = 1;if(len == 2 && isdigit(token[1])){num = token[1] - '0'; } else if(len == 3 && isdigit(token[1]) && isdigit(token[2])){num = (token[1] - '0')*10 + token[2] - '0';} else {valid = 0;}if(valid){if(direction == 'A'){x -= num;} else if(direction == 'D'){x += num;} else if(direction == 'W'){y += num;} else if(direction == 'S'){y -= num;}}token = strtok(NULL, ";");}printf("%d,%d\n", x, y);return 0;
}
18:50=21:29