Remove Last Character of a Stringbuilder

Remove last character of a StringBuilder?

Others have pointed out the deleteCharAt method, but here's another alternative approach:

String prefix = "";
for (String serverId : serverIds) {
sb.append(prefix);
prefix = ",";
sb.append(serverId);
}

Alternatively, use the Joiner class from Guava :)

As of Java 8, StringJoiner is part of the standard JRE.

deleteCharAt or setLength, which way is better to remove last char from a StringBuilder/StringBuffer

Actually, there is very little in it and is probably dependent on hardware and other factors.

The setLength() method simply alters the count and overwrites the unwanted value in the array with a zero byte.

The deleteCharAt() performs an array copy internally, before altering the count. That sounds dramatic, but the array being copied is actually zero-length because you're removing the last character.

I would recommend going for setLength() as it is shorter to type and I think makes it clearer what you are doing. If performance is an issue and, on measuring, you find this is the bottleneck for you, then perhaps you could consider a different algorithm that doesn't require changing the size (as per JB Nizet's answer).

How to remove last character of string buffer in java?

Don't append it in the first place:

for (int i = 0; i < MMqty;i++){
Att.append(m_masi.getSerNo(true));
if (i + 1 < MMqty) Att.append(",");
}

Also, note that if you don't require the synchronization (which you don't appear to in this code), it may be better to use StringBuilder.

How to remove the last string from a stringbuilder?

Yes. You know how wide the " AND " is, so just use StringBuilder#delete:

preparedStatement.delete(preparedStatement.length() - " AND ".length(),
preparedStatement.length()
);

Or, if you're about to turn it into a String anyway, use StringBuilder#substring:

String result = preparedStatement.substring(0,
preparedStatement.length()
- " AND ".length()
);

Best way to remove the last character from a string built with stringbuilder

The simplest and most efficient way is to perform this command:

data.Length--;

by doing this you move the pointer (i.e. last index) back one character but you don't change the mutability of the object. In fact, clearing a StringBuilder is best done with Length as well (but do actually use the Clear() method for clarity instead because that's what its implementation looks like):

data.Length = 0;

again, because it doesn't change the allocation table. Think of it like saying, I don't want to recognize these bytes anymore. Now, even when calling ToString(), it won't recognize anything past its Length, well, it can't. It's a mutable object that allocates more space than what you provide it, it's simply built this way.

StringBuilder remove comma at the end of Last record

Add a check for the last item.

if (i < arrayList.size() - 1) {
stringBuilder.append(" - "+price+",");
} else {
stringBuilder.append(" - "+price);
}

or:

stringBuilder.append(" - "+price);
if (i < arrayList.size() - 1) {
stringBuilder.append(",");
}

How to trim last character from Golang Strings.Builder object?

There's no way to "remove" a character from a strings.Builder object.

What you can do is create the final string by calling sb.String(), and then slice the result to remove the last character:

str := sb.String()
if len(str) > 0 {
str = str[:len(str)-1]
}

Or you could simply not add that final "." in the first place by detecting whether you're at the end or not.

And as a side note, it seems like you're simply trying to format an IP Address? If that's the case, check the type net.IP and the function func net.IPv4(...) IP. You can easily do something like:

str := net.IPv4(10,0,0,1).String()

And as a second side note, that recursive code feels "forced". It seems to me that a simple loop would likely not only be incredibly more efficient, but also more readable.


EDIT: based on your comment, it seems like this is an "interview problem". Link in the comments for anyone else interested.

Problem: given a string s, return all the possible valid IPs by adding three dots.

This is a classic backtracking problem. You can frame it as a tree you have to explore, and you can stop early as soon as one path would provably lead to an invalid result. The tree is that of the "position of the dots".

As a general approach, here's how these problems can be solved.

You create a recursion that has a base case when the "problem is solved", and you return a singleton with that solution. A singleton is a collection with just one element, in this case the valid solution. In some problems it may be helpful to check if the solution is invalid and return an empty collection. Here, it isn't necessary.

If the problem "is not solved", then you generate each "next partial solution", and call the function recursively for the "remaining problems", and combine their results. You finally return that collection of combined results.

Something like this:

func recursiveHelper(s string, parts []string) []string {
if len(s) == 0 {
// Base case, problem solved.
// We assume that if we ever get to
// this point, the solution is valid.
return strings.Join(parts, ".")
}
// We're not at the end, so let's explore
// the tree, collect the results and
// return then
var res []string

// Each candidate solution must consume
// 1 to 3 characters from the string,
// which must be a valid number between
// 0 and 255, with no leading zeroes.
// Say you have a function that generates
// those candidates (exercise: write it).
// You could also inline that code
// here instead, if it's simple enough and
// you're short on time.
for _, c := range genCandidates(s, parts) {
res = append(res, recursiveHelper(s[len(c):], append(parts, c))...)
}
return res
}

The reason it works is that if the part of the tree you're exploring doesn't generate any candidates, it returns an empty slice. That completely stops the exploration of that branch of the tree - the backtracking. When you append the empty slice into the current set of solutions being built, it doesn't change the current set of solution, so you don't get "garbage" into the results slice, ever. Finally, since the helper function is only ever called with an empty string if the call was a result of a VALID candidate, the final call into the base case must yield a valid solution.

More generally, that is, if you see a more complicated backtracking problem that has more complex state, you define a State type that has some helper functions:

type State struct {...}
func (s State) Next() []State {
// return a slice of potential
// candidate states
}
func (s State) Invalid() bool {
// true if this (partial or not) State
// is already provably invalid
}
func (s State) Valid() bool {
// true if this is valid.
// Valid means it solves the problem.
// Note that this is NOT the same as
// !s.Invalid(). It's like you got 3 kinds of
// states: you know for sure it's valid,
// you know for sure it's invalid (and won't ever be made valid), or
// it may be able to produce valid children.
}

You could even define State as an interface for a more "generic" backtracking algo. With that, here's how you solve any backtracking problem:

func backtrack(st State, fn func(State)) {
if st.Valid() {
// found a solution, yield it
fn(st)
}
// find child states
for _, c := range st.Next() {
if c.Invalid() {
// quickly discard this entire branch
continue
}
// continue exploring the tree
backtrack(c, fn)
}
}

You'd call it from your main solution function like this, assuming that you fill that State code to work with IP adresses etc:

initialState := State{...} 
var ips []string
backtrack(initialState, func (sol State) {
// you'll need a function that transforms
// a solution state into the IP address
// it represents
ip := sol.String()
ips = append(ips, ip)
})
return ips

That's all!

StringBuilder Duplicates the last character in the delete

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



Related Topics



Leave a reply



Submit