Java 调用相同(自写)方法时获得不同的结果
首先,很抱歉,这个标题是超级描述性的,但我真的无法用一句话来解释我的问题。 为了解释我在做什么:我正在创建一个字母表,它的开头有一个单字母加密的密钥。我做了一个方法,删除重复的工作很好。我有一些额外的时间做这个任务,所以我一直在到处玩。我发现了不包含重复项的集合 所以当我让集合返回到一个字符串时,我有一个字符串 [s,e,c,u,r….x,y,z] 字符串中包含我不需要的所有字符。所以我用我写的一种方法删除了所有不是字母的东西。当我第一次叫它的时候,我 s e c u r……x y z 一、 只是为了好玩,再次调用该方法。我现在只剩下 secur…xyz 因此,如果有人能告诉我为什么这个方法第一次成功地删除了逗号和括号,但在第二次调用中却没有删除空格,那就太棒了。 作为参考,我的代码Java 调用相同(自写)方法时获得不同的结果,java,set,self,Java,Set,Self,首先,很抱歉,这个标题是超级描述性的,但我真的无法用一句话来解释我的问题。 为了解释我在做什么:我正在创建一个字母表,它的开头有一个单字母加密的密钥。我做了一个方法,删除重复的工作很好。我有一些额外的时间做这个任务,所以我一直在到处玩。我发现了不包含重复项的集合 所以当我让集合返回到一个字符串时,我有一个字符串 [s,e,c,u,r….x,y,z] 字符串中包含我不需要的所有字符。所以我用我写的一种方法删除了所有不是字母的东西。当我第一次叫它的时候,我 s e c u r……x y z 一、 只
public static String createMonoAlphabet(String key){
String crypticAlphabet = key;
crypticAlphabet = crypticAlphabet.concat("abcdefghijklmnopqrstuvwxyz");
//crypticAlphabet = removeDuplicates(crypticAlphabet);
Set alphabet = new LinkedHashSet();
for(int i = 0; i<crypticAlphabet.length(); i++){
alphabet.add(crypticAlphabet.charAt(i));
}
crypticAlphabet = alphabet.toString();
crypticAlphabet = parseInput(crypticAlphabet);
crypticAlphabet = parseInput(crypticAlphabet);
return crypticAlphabet;
}
公共静态字符串createMonoAlphabet(字符串键){
字符串crypticAlphabet=key;
crypticAlphabet=crypticAlphabet.concat(“abcdefghijklmnopqrstuvwxyz”);
//隐式叶状体=移除的复制体(隐式叶状体);
Set alphabet=新LinkedHashSet();
for(int i=0;i您必须在parseInput
方法中反转for循环的顺序。
执行deleteCharAt
操作时,会导致左移,这意味着您将丢失某些字符。颠倒顺序可修复此问题
对于for循环,请尝试以下操作:
对于(int i=buf.length()-1;i>=0;i--)
为了解决您的实际问题,我更改了parseInput
方法以获得更简单的解决方案:
public static String parseInput(String input) {
char[] chars = input.toCharArray();
StringBuilder sb = new StringBuilder();
for(int i = 0; i < chars.length; i++) {
if ((chars[i] >= 65 && chars[i] <= 90) ||
(chars[i] >= 97 && chars[i] <= 122)) {
sb.append(chars[i]);
}
}
return sb.toString();
}
索引为0,找到了一个非字符的[
,因此它将被删除,具有实际数组
0 1 2 3 4
s , e ]
检查元素是否返回到数组中的一个位置,但您的索引将向上滚动1,因此现在索引为1并找到,
(而不是s
!)。这将是这种情况下的输出:
0 1 2 3
s e ]
现在您的索引将是2。请检查空格是否向后移动了1个位置并变为1。这就是您的算法失败的原因
作为侧重点,你应该考虑以下建议:
- 使用集合时,定义容器的类。在这种情况下,您将使用
Set
和LinkedHashSet
- 使用
StringBuilder
而不是StringBuffer
。详细信息
alphabet.toString()调用会添加所有不需要的字符。集合的字符串表示形式始终为:
[项目1、项目2、项目3,…]
要再次将集合转换为字符串,请对其进行迭代并使用StringBuilder创建字符串,例如
StringBuilder builder = new StringBuilder();
for(String s: alphabet) { builder.append(s); }
crypticAlphabet = builder.toString();
关于parseInput
代码的几点说明:
- 您正在迭代StringBuffer并同时修改它(通过调用
deleteCharAt(i)
),这样做通常是个坏主意
- 在Java中,您不应该执行低级操作,比如将字符转换为ASCII值(看起来像C代码)
在我看来,解决问题的最佳方法是使用正则表达式。我会这样写:
public static String parseInput(String input) {
return input.replaceAll("[^a-zA-Z]+","");
}
这意味着用空字符串替换所有非字母的内容。
欢迎这样做!你应该发布你的parseInput
方法的代码。是的,对不起。我想我已经发布了。我只是复制了错误的一位。现在就在上面。疯狂。我想我永远都不会意识到。谢谢。算法中有一个更深层次的问题,我解释了细节。这个更改只会为这些例外情况保存你。@Luiggi、 你在文章中解释的实际上是我的意思,左移,因此缺少一些字符。但感谢你的澄清。@tom我不是说你的解决方案是错误的,它是有效的。但在我看来,你应该避免在读取数组中的值时修改数组,我建议使用时态变量来保存好的值,而不是ch原始数据:)。我不认为这是真正的问题。我测试了这个,在某些条件下仍然需要多次解析。这是你应该回答更大问题的方式。没有理由你应该将字符串哑成一个数据结构,比如一个集合,然后在该集合上调用toString,然后再次解析该字符串。即使你需要做额外的f你应该使用这个机制。你可以考虑一个正则表达式而不是伪ASCII过滤。使用字符类来表示单词字符。是的,我很清楚,我将用一些非常普通的方式来处理这个问题。我是半个新手来编程,我喜欢想出坏主意,慢慢地意识到新的和更好的方法。hings。比其他答案更快、更好、更简单。我喜欢正则表达式,一开始我就玩弄它们。但我似乎无法让它们发挥作用。我想我试图用它们来做更复杂的事情,但后来放弃了。不过,这似乎要简单得多。另外,感谢大家的欢迎!如果我有更多的时间,我可能会用它来完成h并重新编写更多的代码。我知道有很多东西是不好的做法(太多的静态!)。我有一些额外的时间,但不太多!
StringBuilder builder = new StringBuilder();
for(String s: alphabet) { builder.append(s); }
crypticAlphabet = builder.toString();
public static String parseInput(String input) {
return input.replaceAll("[^a-zA-Z]+","");
}