我正在研究Java中一个相当独特的编码情况。我试图写的程序的目的是采取业余无线电呼号,将呼号中的字母转换为列表或其他结构定义的数字,将数字视为其面整数值,并运行这些数字通过几个数学运算,最后输出一个独特的“用户代码”。字符的长度以及数字本身将根据用户的呼号在用户之间变化,这很好。我遇到的最大障碍是我不希望字母以1-26或0-25类型模式分配值。我会在片刻发布我的代码给你看。目前,这个用户代码的最终用法对于这个例子并不重要,但是可以说,因为我将是唯一使用这个特定代码示例的人,所以我并不十分关心进行有效性检查等等。手动确保输入数据的完整性。有了这个说法,我确实有一个工作解决方案,我将在这里发布,但我的问题不是“它不起作用”,因为它确实有效,我的问题是,在我看来,它是臃肿的,有些东西告诉我我可以大大削减它。以下是代码,以下是我考虑但拒绝的一些备选方案:
import java.util.*;
import java.io.*;
public class UserCode
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int baseNumber = 0;
int finalNumber;
String callSign;
System.out.println("Enter CallSign for Code Generation: ");
callSign = in.nextLine();
String s = callSign.toUpperCase();
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (Character.isDigit(c))
{
int l = Character.getNumericValue(c);
baseNumber = baseNumber + l;
}
else if (Character.isLetter(c))
{
int letNum = 0;
switch (c)
{
case 'A':
letNum = 23;
break;
case 'B':
letNum = 17;
break;
case 'C':
letNum = 5;
break;
case 'D':
letNum = 11;
break;
case 'E':
letNum = 34;
break;
case 'F':
letNum = 18;
break;
case 'G':
letNum = 13;
break;
case 'H':
letNum = 31;
break;
case 'I':
letNum = 27;
break;
case 'J':
letNum = 25;
break;
case 'K':
letNum = 7;
break;
case 'L':
letNum = 25;
break;
case 'M':
letNum = 33;
break;
case 'N':
letNum = 26;
break;
case 'O':
letNum = 28;
break;
case 'P':
letNum = 16;
break;
case 'Q':
letNum = 14;
break;
case 'R':
letNum = 2;
break;
case 'S':
letNum = 4;
break;
case 'T':
letNum = 6;
break;
case 'U':
letNum = 8;
break;
case 'V':
letNum = 10;
break;
case 'W':
letNum = 37;
break;
case 'X':
letNum = 12;
break;
case 'Y':
letNum = 3;
break;
case 'Z':
letNum = 1;
break;
default:
System.out.println("Call Contains a bad character. Try again. \n");
}
baseNumber = baseNumber + letNum;
}
}
System.out.println("\n");
String baseStr = Integer.toString(baseNumber);
System.out.println("The Base number is: " + baseStr + "\n");
int sMod = baseNumber%7;
String sModStr = Integer.toString(sMod);
System.out.println("The Check Digit is: " + sModStr + "\n");
String combine = baseStr + sModStr;
int nextOp = Integer.parseInt(combine);
finalNumber = nextOp * nextOp;
String finalStr = Integer.toString(finalNumber);
System.out.println("The User Code is: " + finalStr + "\n");
}
}
好的,正如我所说的这段代码有效,但它很长。我考虑了一些替代方案,其中没有一个会真正起作用。第一个是Enum,但这显然超出了我的参数,因为它产生1-26递增的模式。使用各种for {}循环有几种变体,但结果是相同的。我甚至考虑过一个新的HashMap和map.put语句,但这只是略微缩短了,在我看来,创建一个hashmap实际上会比我当前的解决方案使用更多的内存。正如你所看到的,我没有.split或者使用.toCharArray(),因为它们在内存中创建了我不需要的独立实体。我需要的所有信息都已包含在字符串本身中,除了我选择的数值。最后,我可以用这个赋值代码创建另一个类文件,但结果是一样的:长度本身没有被改变它已经分布在两个文件上(实际上在调用方法时增加了。)
把这个放在这里,任何人都可以看到我可以缩短这些代码的方法,特别是在switch {}块的区域,并且仍然保留相同的数值相同的结果?我对这方面可以提出的任何建议非常感兴趣。顺便说一下,我没有提到这个,但这不是一个学校作业,这是一个个人项目,虽然我的Java知识水平与初学者的第一个Java类LOL有关。感谢
答案 0 :(得分:2)
如果您想坚持使用此逻辑,请使用HashMap<Character, Integer>
并仅设置一次,如map.put('Z', 1);
等值,那么您就不需要切换。您可以使用以下内容获取值:map.get('Z');
,每次返回1
如果需要,它易于实现并且易于更改代码
答案 1 :(得分:0)
创建一个对应整数的数组:
int[] letnums = {23, 17, 5, ... };
char c = s.charAt(i);
if (Character.isLetter(c)) {
int letnum = letnums(c);
...
}