1

首先,对不起,标题是超级描述性的,但老实说,我无法用一句话来解释我的问题。解释我在做什么:我正在创建一个字母表,该字母表的开头有一个用于单字母加密的密钥。我做了一个删除重复项的方法,效果很好。我有一些额外的时间来做这个评估,所以我一直在玩。我发现了不包含重复项的集合。

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

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

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

安全....xyz

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

安全....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

4 回答 4

2

parseInput关于您的代码的几点说明:

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

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

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

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

这意味着用空字符串替换所有不是字母的东西。欢迎!

于 2012-09-26T07:05:02.350 回答
1

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

[项目1,项目2,项目3,...]

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

StringBuilder builder = new StringBuilder();
for(String s: alphabet) { builder.append(s); }
crypticAlphabet = builder.toString();
于 2012-09-26T06:41:51.470 回答
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>and LinkedHashSet<Character>
  • 使用StringBuilder而不是StringBuffer. 更多关于它的信息
于 2012-09-26T06:39:50.187 回答
0

您必须反转parseInput方法中 for 循环的顺序。执行 adeleteCharAt时会引发左移,这意味着您会错过某些字符。颠倒顺序可以解决这个问题。

为您的 for 循环尝试以下操作:

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

于 2012-09-26T06:38:18.323 回答