调用相同(自写)方法时获得不同的结果

时间:2012-09-26 06:19:23

标签: java set self

首先,抱歉Tittle是超级描述性的,但老实说,我无法用一句话来解释我的问题。 为了解释我正在做什么:我正在创建一个字母表,在单词字母加密的开头有一个键。我做了一个方法,删除了重复的工作正常。我有一些额外的时间用于这种分配,所以我一直在玩。我发现了不包含重复项的集合。

因此,当我将Set返回给字符串时,我有一个读取

的字符串
  

[s,e,c,u,r ..... x,y,z]

字符串中包含我不需要的所有这些字符。所以我使用我编写的方法删除任何不是字母的东西。当我第一次打电话时,我得到

  

s e c u r .... x y z

我,只是为了好玩,再次调用该方法。我现在离开了

  

SECUR .... XYZ

因此,如果任何人可以告诉我为什么方法成功删除逗号和括号第一次但不是空格在第二次调用中删除了空格,那将是非常棒的。 作为参考,我的代码

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;
}        

这是使用该集的方法。作为一个注释,在我刚刚在这里玩游戏之前我从来没有使用它们,所以如果它的不良做法或其他一切都很好。请随时告诉我,但我现在并不那么担心 现在为删除非字母的方法

    public static String parseInput(String input){
    StringBuffer buf = new StringBuffer(input);

    for(int i = 0; i < buf.length(); i++){
        char c = buf.charAt(i);
        if(!(((int)c >= 65 && (int)c <= 90) || 
                ((int)c >= 97 && (int)c <= 122))){
            System.out.print(buf.charAt(i));
            buf =  buf.deleteCharAt(i);
        }   
    }
    System.out.print(".");
    System.out.println();
    input = buf.toString();
    return input;
}

4 个答案:

答案 0 :(得分:2)

关于parseInput代码的几点评论:

  • 您正在迭代思考您的StringBuffer并同时修改它(通过调用deleteCharAt(i))。做这种事情通常是个坏主意。

  • 在Java中,您不应该执行低级操作,例如将char转换为其ASCII值(它看起来像C代码)

在我看来,解决问题的最佳方法是使用正则表达式。我会写这样的东西:

public static String parseInput(String input) {
    return input.replaceAll("[^a-zA-Z]+","");
}

这意味着用空字符串替换不是字母的所有内容。 欢迎来到SO!

答案 1 :(得分:1)

alphabet.toString()调用会添加您不需要的所有字符。集合的String表示始终为:

  

[item1,item2,item3,...]

要再次将该集转换为String,请对其进行迭代并使用StringBuilder创建String,例如

StringBuilder builder = new StringBuilder();
for(String s: alphabet) { builder.append(s); }
crypticAlphabet = builder.toString();

答案 2 :(得分:0)

您必须在parseInput方法中反转for循环的顺序。 在做deleteCharAt时你会引发左移意味着你会错过某些角色。反转订单会修复此问题。

请尝试以下for for循环:

for (int i = buf.length() - 1; i >= 0; i--)

答案 3 :(得分:0)

为了解决您的实际问题,我更改了您的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();
}

你的后期代码遇到了问题:使用索引从数组中删除元素然后移动到下一个索引是不好的。这将是使用字符串[s, e](包括空格)的示例:

第一次,你将拥有这个数组(更短的形式):

0 1 2 3 4 5
[ s ,   e ]

索引为0,发现[为非字符,因此将删除,具有实际数组

0 1 2 3 4
s ,   e ]

检查元素是否返回数组中的一个位置,但您的索引将向上滚动1,因此现在Index为1并找到,(不是s!)。这将是该案例的输出:

0 1 2 3
s   e ]

现在你的索引将是2.检查空格是否向后移动1位并变为1.这就是你的算法失败的原因。

作为附注,您应该考虑以下建议:

  • 使用Collection时,请定义容器的类。在这种情况下,您将使用Set<Character>LinkedHashSet<Character>
  • 使用StringBuilder代替StringBuffer。关于它的更多信息here