题目描述
此题目为LintCode上的一个题目:模糊坐标
描述
我们有一些二维坐标,如"(1, 3)"
或 "(2, 0.5)"
,然后我们移除所有逗号,小数点和空格,得到一个字符串S
。返回所有可能的原始字符串到一个列表中。
原始的坐标表示法不会存在多余的零,所以不会出现类似于"00", “0.0”, “0.00”, “1.0”, “001”, "00.01"或一些其他更小的数来表示坐标。此外,一个小数点前至少存在一个数,所以也不会出现“.1”形式的数字。
最后返回的列表可以是任意顺序的。而且注意返回的两个数字中间(逗号之后)都有一个空格。
4 <= S.length <= 12
.S[0]
= “(”,S[S.length - 1]
= “)”, 且字符串S
中的其他元素都是数字。
样例
样例1
输入:"(00011)"
输出:["(0.001, 1)", "(0, 0.011)"]
解释:0.0, 00, 0001 或 00.01 是不被允许的。
样例2
输入:"(100)"
输出:[(10, 0)]
解释:1.0 是不被允许的。
解答
思路
- 校验输入字符串的正确性(此步骤在提交答案时可以省略,LintCode输入的字符串都是正确的,但自己写代码时要养成良好的习惯:对输入参数校验,要有防御式编程的思想)
- 使用暴力破解的方法找出左边的坐标
- 左边的坐标检验通过后找出右边的坐标
- 右边的坐标也校验通过了就组装出一条结果放入结果集合中
- 重复2、3、4步骤,直到字符串解析完毕
- 返回结果
代码
import java.util.ArrayList;
import java.util.List;
public class Coordinate {
/**
* 获取结果(符合条件的坐标的集合)
* @param S:
* @return: nothing
*/
public List<String> ambiguousCoordinates(String S) {
List<String> result = new ArrayList<String>();
if (verifySimpleStr(S)){
String num = S.substring(1, S.length()-1);
for (int i = 1; i < num.length(); i++){
String leftNum = num.substring(0, i);
if (verifyNum(leftNum)){
String rightNum = num.substring(i);
if (verifyNum(rightNum)){
result.add(buildResultStr(leftNum, rightNum));
}
if (rightNum.length() > 1){
for (int k = 1; k < rightNum.length(); k++){
String rightNumPoint = rightNum.substring(0, k)+"."+rightNum.substring(k);
if (verifyNum(rightNumPoint)){
result.add(buildResultStr(leftNum, rightNumPoint));
}
}
}
}
if (leftNum.length() > 1){
for (int j = 1; j < leftNum.length(); j++){
String leftNumPoint = leftNum.substring(0, j)+"."+leftNum.substring(j);
if (verifyNum(leftNumPoint)){
String rightNum = num.substring(i);
if (verifyNum(rightNum)){
result.add(buildResultStr(leftNumPoint, rightNum));
}
if (rightNum.length() > 1){
for (int k = 1; k < rightNum.length(); k++){
String rightNumPoint = rightNum.substring(0, k)+"."+rightNum.substring(k);
if (verifyNum(rightNumPoint)){
result.add(buildResultStr(leftNumPoint, rightNumPoint));
}
}
}
}
}
}
}
}
return result;
}
/**
* 验证输入的字符串是否符合条件
* @param simpleStr
* @return
*/
public boolean verifySimpleStr(String simpleStr){
if (simpleStr == null || simpleStr.length() < 4){
return false;
}
if (!simpleStr.startsWith("(") || !simpleStr.endsWith(")")){
return false;
}
String s = simpleStr.substring(1, simpleStr.length()-1);
try {
Long.parseLong(s);
}catch (NumberFormatException e){
return false;
}
return true;
}
/**
* 校验是否为符合坐标条件的字符串
* @param num
* @return
*/
public boolean verifyNum(String num){
if (num != null && num.length() > 0){
String after = "";
if (num.contains(".")){
Double d = null;
try {
d = Double.parseDouble(num);
after = d.toString();
if (after.endsWith(".0")){
return false;
}
}catch (NumberFormatException e){
return false;
}
}else {
Long l = null;
try {
l = Long.parseLong(num);
after = l.toString();
}catch (NumberFormatException e){
return false;
}
}
if (after.equals(num)){
return true;
}
}
return false;
}
/**
* 组装一条结果
* @param leftNum
* @param rightNum
* @return
*/
public String buildResultStr(String leftNum, String rightNum){
return "("+leftNum+", "+rightNum+")";
}
}
结语
大学毕业后就很少研究算法了,工作几年算法都还给老师了。。。。。。
此文章记录我第一次做这道算法题的思路和方法,希望以后能有更好的解题方法。
PS:本人的正则表达式水平实在太水,所以校验字符串的那几个方法就没用正则的方式,以后要改正了~