【问题标题】:Java replace characters in a TextFile - Alice In WonderlandJava 替换 TextFile 中的字符 - 爱丽丝梦游仙境
【发布时间】:2016-04-19 16:30:48
【问题描述】:

我正在尝试为 TextFiles 制作压缩器,但在替换字符时遇到了困难。

这是我的代码:

compress.setOnAction(event ->
    {
        String line;
        try(BufferedReader reader = new BufferedReader(new FileReader(newFile)))
        {
            while ((line = reader.readLine()) != null)
            {
                int length = line.length();
                String newLine = "";


                for (int i = 1; i < length; i++)
                {
                    int c = line.charAt(i);

                    if (c == line.charAt(i - 1))
                    {

                    }
                }
            }

        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    });

所以我想做的是:我想找到两个字符相等的所有单词,如果它们在旁边(比如“Took”)。当 if 语句为真时,我想替换两个等号字符的第一个字母,所以它看起来像:'T2ok'。

我已经尝试了很多东西,我总是得到一个 ArrayOutOfbounds、StringOutOfbounds 等等......

希望有人有一个很好的答案:-)

问候

【问题讨论】:

  • Java 中的字符串是不可变对象,因此:您的问题的答案是使用StringBuilder 而不是StringCheck this answer 了解更多信息。
  • 对标题中的 Alice 部分感到好奇,那是什么意思?

标签: java arrays replace char


【解决方案1】:

创建一个压缩String的方法,如下所示:
使用 while 循环遍历每个字符。在另一个嵌套的 while 循环中计算重复项,该循环在找到重复项时递增当前索引并将它们从写入输出中跳过。此外,这也计算了它们的出现次数。

public String compress(String input){
    int length = input.length(); // length of input
    int ix = 0;                  // actual index in input
    char c;                      // actual read character
    int ccounter;                // occurrence counter of actual character
    StringBuilder output =       // the output
            new StringBuilder(length);

    // loop over every character in input
    while(ix < length){
        // read character at actual index then inc index
        c = input.charAt(ix++);
        // we count one occurrence of this character here
        ccounter = 1;
        // while not reached end of line and next character
        // is the same as previously read
        while(ix < length && input.charAt(ix) == c){
            // inc index means skip this character
            ix++;
            // and inc character occurence counter
            ccounter++;
        }
        // if more than one character occurence is counted
        if(ccounter > 1){
            // print the character count
            output.append(ccounter);
        }
        // print the actual character
        output.append(c);
    }
    // return the full compressed output
    return output.toString();
}

现在您可以使用此方法使用java8 技术创建文件输入到输出流。

// create input stream that reads line by line, create output writer
try (Stream<String> input = Files.lines(Paths.get("input.txt"));
     PrintWriter output = new PrintWriter("output.txt", "UTF-8")){
    // compress each input stream line, and print to output
    input.map(s -> compress(s)).forEachOrdered(output::println);
} catch (IOException e) {
    e.printStackTrace();
}

如果你真的想。您可以删除输入文件并在之后重命名输出文件

Files.move(Paths.get("output.txt"), Paths.get("input.txt"),StandardCopyOption.REPLACE_EXISTING);

我认为这是做你想做的最有效的方法。

【讨论】:

  • 我明白了这个想法,但我有点困惑你在这里做什么?两个 ix
  • 添加了一些 cmets。希望这会有所帮助。
  • 您将如何将更改添加到文件中?我希望它像:T2OK,而不是 TOOK。希望你能明白我的意思:)
  • 亲爱的北极领主。这个答案真的很棒!太感谢了。喜欢这个解释,所以我可以坚持下去并且不会迷失在翻译中。它成功了。虽然文件似乎没有缩小,所以我又在路上想出一个更好的自制想法:D。周末愉快。
【解决方案2】:

试试这个:

    StringBuilder sb = new StringBuilder();
    String line;
    try(BufferedReader reader = new BufferedReader(new FileReader(newFile)))
    {
        while ((line = reader.readLine()) != null)
        {

            if (!line.isEmpty()) {

                //clear states
                boolean matchedPreviously = false;
                char last = line.charAt(0);

                sb.setLength(0);
                sb.append(last);

                for (int i = 1; i < line.length(); i++) {
                    char c = line.charAt(i);

                    if (!matchedPreviously && c == last) {

                        sb.setLength(sb.length()-1);
                        sb.append(2);

                        matchedPreviously = true;
                    } else matchedPreviously = false;

                    sb.append(last = c);
                }
                System.out.println(sb.toString());
            }
        }

    }
    catch (IOException ex)
    {
        ex.printStackTrace();
    }

此解决方案仅使用单个循环,但只能找到长度为 2 的出现

【讨论】:

  • 我相信这是一个很好的解决方案。您将如何将其保存到我们正在阅读的文件中? :)
  • 最简单的方法是将新数据写入新文件并在最后切换文件。但我猜你想进行流式编辑?
  • 流媒体编辑会很好,除非很难做到这一点?我在JavaFX中制作了它,并制作了一个丑陋的按钮来压缩文件,当我按下它时。这就是上面的代码出现的地方。
  • 您可以使用 RandomAccessFile 同时读取和写入文件,但您必须自己计算更改的位置,并避免使用 BufferedReader。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
相关资源
最近更新 更多