StringBuilder在删除操作时会复制最后一个字符。

huangapple go评论68阅读模式
英文:

StringBuilder Duplicates the last character in the delete

问题

I do not know the site, and I have only asked one question here. I have no idea - how to handle a code problem. I tried a lot - but I could not fix.
I use StringBuilder - for because of its benefits according to the standard string

I want to delete the first character in the string - but the character that appears in the last place - is duplicated - in the last two places.

for example:
i have the String abcdef, when i delete - the first instace - 'a':
i got back the String bcdeff
well i try - to set the length of the String to original length minus one - but this dont give any result.
i try also - to set the string to new String - and after that - send the String that i was save in tmp string - but this do help either.
public void appendBuffer(StringBuilder dictionary)
{
    for (int i = 0; i < appendToWindowBuffer; i++) {
        if (dictionary.length() == windowSize) {
            dictionary.deleteCharAt(0);
        }
        if (nextByteIndex < source.length) {
            dictionary.append((char) source[nextByteIndex]);
            nextByteIndex++;
        } else {
            currentLookaheadBufferSize--;
        }
        if (currentSearchBufferSize < searchBufferSize) {
            currentSearchBufferSize++;
        }
    }
    appendToWindowBuffer = 0;
}
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("main");
        String inPath = "C:\\Users\\avraam\\Documents\\final-assignment\\LZ77\\source.txt";
        String outPath = "C:\\Users\\avraam\\Documents\\final-assignment\\LZ77\\encoded.txt";
        String decompressedPath = "C:\\Users\\avraam\\Documents\\final-assignment\\LZ77\\decoded.txt";
        int windowSize = 14;
        int lookaheadBufferSize = 6;
        LZ77 compress = new LZ77(inPath, outPath, windowSize, lookaheadBufferSize);
        compress.compress();
    }
}
public class Match {
    protected int length;
    protected int offset;
    protected String value;

    public Match(int length, int offset, String value) {
        this.length = length;
        this.offset = offset;
        this.value = value;
    }

    public void SetOffset(int offset) { this.offset = offset; }
    public void SetLength(int length) { this.length = length; }
    public void SetValue(String value) { this.value = value; }
    public void AddValue(char value) { this.value += value; }

    public void Reset() {
        this.offset = 0;
        this.length = 0;
        this.value = "";
    }
}
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;

public class LZ77 {
    private String inPath = null;
    private String outPath = null;
    private File inFile;
    private File outFile;
    private final int windowSize;
    private final int lookaheadBufferSize;
    private final int searchBufferSize;
    private int nextByteIndex = 0;
    private int currentSearchBufferSize = 0;
    private int currentLookaheadBufferSize = 0;
    private int appendToWindowBuffer = 0;
    private byte[] source = null;

    public LZ77(String inPath, String outPath, int windowSize, int lookaheadBufferSize) throws IOException {
        this.inPath = inPath;
        this.outPath = outPath;
        this.inFile = new File(inPath);
        this.outFile = new File(outPath);
        this.windowSize = windowSize;
        this.lookaheadBufferSize = lookaheadBufferSize;
        this.searchBufferSize = windowSize - lookaheadBufferSize;
        this.source = Files.readAllBytes(inFile.toPath());
    }

    public void compress() throws IOException {
        System.out.println("compress");
        System.out.println("read the file.");
        System.out.println("check if source array work: ");
        for (int element : source) {
            System.out.print((char) element + "");
        }
        System.out.println("call to bufferInitialize function");
        StringBuilder dictionary = new StringBuilder();
        bufferInitialize(dictionary);
        System.out.println(dictionary.toString());
        StringBuilder compressed = new StringBuilder();
        encode(dictionary, compressed);
    }

    public void bufferInitialize(StringBuilder dictionary) {
        System.out.println("bufferInitialize");
        for (int i = 0; i < lookaheadBufferSize; i++) {
            dictionary.append((char) source[nextByteIndex]);
            nextByteIndex++;
            currentLookaheadBufferSize++;
        }
    }

    public void encode(StringBuilder dictionary, StringBuilder compressed) {
        while (currentLookaheadBufferSize > 0) {
            Match match = findMatch(dictionary);
            System.out.print("<" + match.offset + "," + match.length + "," +
                    dictionary.charAt(currentSearchBufferSize + match.length) + ">");
            appendToWindowBuffer = increaseBuffer(match.length);
            appendBuffer(dictionary);
        }
    }

    public Match findMatch(StringBuilder dictionary) {
        Match match = new Match(0, 0, "");
        String matchedString = null;
        int offset;
        int matchLookAheadIndex = currentSearchBufferSize;
        if (!haveAnyMatch(dictionary)) {
            addMatch();
        } else {
            matchedString = "" + dictionary.charAt(matchLookAheadIndex);
            offset = findMatchIndex(dictionary, matchedString);
            while (offset != -1) {
                match.SetLength(match.length + 1);
                match.SetOffset(offset);
                match.SetValue(matchedString);
                matchLookAheadIndex++;
                matchedString += dictionary.charAt(matchLookAheadIndex);
                offset = findMatchIndex(dictionary, matchedString);
            }
        }
        return match;
    }

    public int findMatchIndex(StringBuilder dictionary, String value) {
        int stringLength = value.length();
        String tmpMatch = null;
        int offsetMatch;
        for (int i = currentSearchBufferSize - 1; i >= 0; i--) {
            tmpMatch = dictionary.substring(i, i + stringLength);
            offsetMatch = currentSearchBufferSize - i;
            if (tmpMatch.equals(value)) {
                System.out.println("data was match is searchWindow");
                System.out.println("the offset from LookAHead is: " + offsetMatch);
                return offsetMatch;
            }
        }
        return -1;
    }

    public boolean haveAnyMatch(StringBuilder dictionary) {
        if (currentSearchBufferSize == 0) {
            System.out.println("dont have match - search buffer is empty now");
            return false;
        }
        if (!isExistInSearchBuffer(dictionary, dictionary.charAt(currentSearchBufferSize))) {
            System.out.println("dont have match - the first character in lookAheadBuffer wasn't found in searchBuffer");
            return false;
        }
        return true;
    }

    public boolean isExistInSearchBuffer(StringBuilder dictionary, char isCharAtDictionary) {
        for (int i = 0; i < currentSearchBufferSize; i++) {
            if (dictionary.charAt(i) == isCharAtDictionary) {
                return true;
            }
        }
        return false;
    }

    public int increaseBuffer(int matchLength) {
        return 1 +

<details>
<summary>英文:</summary>

I do not know the site, and I have only asked one question here. I have no idea - how to handle a code problem. I tried a lot - but I could not fix.
I use StringBuilder - for because of its benefits according to the standard string

I want to delete the first character in the string - but the character that appears in the last place - is duplicated - in the last two places.

for example:
i have the String abcdef, when i delete - the first instace - &#39;a&#39;:
i got back the String bcdeff
well i try - to set the length of the String to original length minus one - but this dont give any result.
i try also - to set the string to new String - and after that - send the String that i was save in tmp string - but this do help either.

public void appendBuffer(StringBuilder dictionary)
{
for (int i = 0; i &lt; appendToWindowBuffer; i++) {
if(dictionary.length() == windowSize)
{
dictionary.deleteCharAt(0);
}
if(nextByteIndex&lt;source.length  )
{
dictionary.append((char)source[nextByteIndex]);
nextByteIndex++;
}
else
{
currentLookaheadBufferSize--;
}
if(currentSearchBufferSize &lt; searchBufferSize)
{
currentSearchBufferSize++;
}
}
appendToWindowBuffer = 0;
}
full code:
main class

import java.io.IOException;

public class Main {
public static void main(String[] args) throws IOException
{
System.out.println("main");
String inPath = "C:\Users\avraam\Documents\final-assignment\LZ77\source.txt";
String outPath = "C:\Users\avraam\Documents\final-assignment\LZ77\encoded.txt";
String decompressedPath = "C:\Users\avraam\Documents\final-assignment\LZ77\decoded.txt";
int windowSize = 14;
int lookaheadBufferSize = 6;
LZ77 compress = new LZ77(inPath,outPath,windowSize,lookaheadBufferSize);
compress.compress();

}

}


match class

public class Match {
protected int length;
protected int offset;
protected String value;

public Match(int length, int offset, String value)
{
this.length=length;
this.offset=offset;
this.value = value;
}
public void SetOffset(int offset) { this.offset = offset; }
public void SetLength(int length) { this.length = length; }
public void SetValue(String value) { this.value = value; }
public void AddValue(char value) { this.value += value; }
public void Reset()
{
this.offset = 0;
this.length = 0;
this.value = &quot;&quot;;
}

}


LZ77 class

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Arrays;

public class LZ77 {
private String inPath = null;
private String outPath = null;
private File inFile;
private File outFile;
private final int windowSize;
private final int lookaheadBufferSize;
private final int searchBufferSize;
private int nextByteIndex = 0;
//private int lookAheadIndex = 0; //not always should be (windowsize - lookaheadBufferSize.) in the end maybr will be less character in the lookAhead buffer. the index when LookAhead start is equel to the length of SearchBuffer
private int currentSearchBufferSize = 0;
private int currentLookaheadBufferSize = 0;
private int appendToWindowBuffer = 0;
private byte[] source = null;

public LZ77(String inPath,String outPath,int windowSize,int lookaheadBufferSize) throws IOException
{
this.inPath = inPath;
this.outPath = outPath;
this.inFile = new File(inPath);
this.outFile = new File(outPath);
this.windowSize = windowSize;
this.lookaheadBufferSize = lookaheadBufferSize;
this.searchBufferSize = windowSize - lookaheadBufferSize;
this.source = Files.readAllBytes(inFile.toPath());
}
public void compress() throws IOException
{
/*
*   1. create whole windowBuffer (named - `dictionary`)- that will by used by lookahead and by search Buffers.
*   2. create compressed data - where the data that compressed will be send. 
*	3. initialize dictionary - look a head buffer by giving it the size of `lookaheadBuffer`.
*	4. start encode.
*	5. make the encode.
*/
System.out.println(&quot;compress&quot;);
System.out.println(&quot;read the file.&quot;);
System.out.println(&quot;check if source array work: &quot;);
for (int element: source) {
System.out.print((char)element + &quot;&quot;);
}
System.out.println(&quot;call to bufferInitialize function&quot;);
StringBuilder dictionary = new StringBuilder();
bufferInitialize(dictionary);
System.out.println(dictionary.toString());
StringBuilder compressed = new StringBuilder();		
encode(dictionary,compressed);
}
public void bufferInitialize(StringBuilder dictionary)
{
System.out.println(&quot;bufferInitialize&quot;);
for (int i = 0; i &lt; lookaheadBufferSize; i++) {
dictionary.append((char)source[nextByteIndex]);
nextByteIndex++;
currentLookaheadBufferSize++;
}
// initialize the buffer in the beginning with look a head buffer.
}
public void bufferUpdate()
{
// gets int length - and read those number of bytes - from `inPath` source file.
}
public void encode(StringBuilder dictionary,StringBuilder compressed)
{
//while(nextByteIndex &lt; source.length)
while(currentLookaheadBufferSize &gt; 0)
{
Match match = findMatch(dictionary);
System.out.print(&quot;&lt;&quot;+match.offset + &quot;,&quot;+match.length+&quot;,&quot;+ dictionary.charAt(currentSearchBufferSize + match.length) + &quot;&gt;&quot;);
appendToWindowBuffer = increaseBuffer(match.length);
appendBuffer(dictionary);
}
/**
* do while you reach to the end of the file
*	 check if there any possible match
* 		if do so
* 		find the maxMatch try always to add another character DONE
* 	call update function - 
* the function will update the 
* windowbuffer(dictionary), DONE
* nextByteIndex and DONE
* the position of the index that begins the lookAheadBuffer 
* and size of the lookahead and 
* search buffers, and 
* reset the appendToWindowBuffer. DONE
*/		
}
public void convertStringToBits()
{
}
public Match findMatch(StringBuilder dictionary)
{
/**
* function get the window buffer - and index to start.
* the function will be find the max match that starts from index 0 to index start (we cant start search after the `start index`) 
* because this parts belong to the look a head buffer.
* @param 
* @return
*/
Match match= new Match(0,0, &quot;&quot;);
String matchedString = null;
int offset;
int matchLookAheadIndex = currentSearchBufferSize;
if(!haveAnyMatch(dictionary))
{
addMatch();
}
else {
matchedString = &quot;&quot; + dictionary.charAt(matchLookAheadIndex);
offset = findMatchIndex(dictionary,matchedString);
while(offset != -1)
{
match.SetLength(match.length + 1);
match.SetOffset(offset);
match.SetValue(matchedString);
matchLookAheadIndex++;
matchedString +=dictionary.charAt(matchLookAheadIndex);
offset = findMatchIndex(dictionary,matchedString);
}
}
return match;
}
public int findMatchIndex(StringBuilder dictionary,String value)
{
int stringLength = value.length();
String tmpMatch = null;
int offsetMatch;
for (int i = currentSearchBufferSize - 1; i &gt;=0; i--) 
{
tmpMatch = dictionary.substring(i, i +stringLength );
offsetMatch = currentSearchBufferSize - i;
if(tmpMatch.equals(value))
{
System.out.println(&quot;data was match is searchWindow&quot;);
System.out.println(&quot;the offset from LookAHead is: &quot; + offsetMatch);
return offsetMatch;
}
}
return -1;
}
public boolean haveAnyMatch(StringBuilder dictionary)
{
if (currentSearchBufferSize == 0)
{
System.out.println(&quot;dont have match - search buffer is empty now&quot;);
return false;
}
if(!isExistInSearchBuffer(dictionary,dictionary.charAt(currentSearchBufferSize)))	
{
System.out.println(&quot;dont have match - the first character in lookAheadBuffer wasn&#39;t found in searchBuffer&quot;);
return false;
}
return true;
/*
* check: 
* if search buffer is empty 
* if the needed character isn&#39;t exist in the search buffer
* if the current value is big enough - and match was not found.
*/
}
public boolean isExistInSearchBuffer(StringBuilder dictionary, char isCharAtDictionary)
{
for (int i = 0; i &lt; currentSearchBufferSize; i++) {
if(dictionary.charAt(i) == isCharAtDictionary)
{
return true;
}
}
return false;
}
public void nextMatch(StringBuilder dictionary)
{
/**
* @param: value, window buffer. 
* @description: find the current match with the needed value in the search buffer boundaries.
*/
}
public int increaseBuffer(int matchLength)
{
return 1 + matchLength;
/*
* return int - that calulate by how many byte we need to increase the buffer
*/
}
public void addMatch()
{
}
public void addBitSize() {
}
public void appendBuffer(StringBuilder dictionary)
{
for (int i = 0; i &lt; appendToWindowBuffer; i++) {
if(dictionary.length() == windowSize)
{
dictionary.deleteCharAt(0);
}
if(nextByteIndex&lt;source.length  )
{
dictionary.append((char)source[nextByteIndex]);
nextByteIndex++;
}
else
{
currentLookaheadBufferSize--;
}
if(currentSearchBufferSize &lt; searchBufferSize)
{
currentSearchBufferSize++;
}
}
appendToWindowBuffer = 0;
}

}


</details>
# 答案1
**得分**: 2
这似乎有效:
```java
StringBuilder builder = new StringBuilder("abcdef");
builder.deleteCharAt(0);
System.out.println(builder.toString());

输出:bcdef

你是如何做到的?

英文:

This seems to work:

StringBuilder builder = new StringBuilder(&quot;abcdef&quot;);
builder.deleteCharAt(0);
System.out.println(builder.toString());

Prints: bcdef

How are you doing it?

答案2

得分: 0

以下是翻译好的内容:

适用于我的解决方案:
我需要编写解压缩 - 到输出文件。
我注册到文件 - 以CHAR方式 - 这是不正确的 - 需要以BYTE方式注册输出。

我错误的方法:

	private void writeDecode (StringBuilder decompress) throws IOException
	{
		Writer write = new FileWriter(this.outFile);
		write.write(decompress.toString());
		write.close();
	}

正确的方法:

	private void WriteToFile(StringBuilder decodedData) throws IOException
	{
		FileOutputStream outputFileStream = new FileOutputStream(this.outPath); 
		for(int i = 0; i < decodedData.length(); i++)
		{
			byte currentByte = (byte)decodedData.charAt(i);
			outputFileStream.write(currentByte);
		}
		outputFileStream.close();
	}

我需要以BYTE方式在文件中注册 - 这是正确的方式。

英文:

the solution that work for me:
i need to write the decompress - to outout file.
I registered to the file - in CHAR - this is not true - need to register output in BYTE

WORNG WAY THAT I DO:

	private void writeDecode (StringBuilder decompress) throws IOException
{
Writer write = new FileWriter(this.outFile);
write.write(decompress.toString());
write.close();
}

THE CORRECT WAY

	private void WriteToFile(StringBuilder decodedData) throws IOException
{
FileOutputStream outputFileStream = new FileOutputStream(this.outPath); 
for(int i = 0; i &lt; decodedData.length(); i++)
{
byte currentByte = (byte)decodedData.charAt(i);
outputFileStream.write(currentByte);
}
outputFileStream.close();
}

I need to register in the file in BYTE - this is the right way.

huangapple
  • 本文由 发表于 2020年8月16日 04:11:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/63430409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定