Java find difference between characters in StringBuffer - java

I'm working on an Anagram program and I'm currently working on a method called diff which should return a StringBuffer containing the chars that are in the first StringBuffer but not in the second one. So for example if the StringBuffers are abba and acca, then my diff method should return bb. So far I currently have loop with an if statement but it's not working. Any help would be appreciated. Thanks
public StringBuffer diff(){
StringBuffer diffVal = null;
for (int i =0; i < sBuffer1.length(); i++){
String let1 = String.valueOf(sBuffer1);
if (sBuffer2.indexOf(let1) == -1 ){
}
}
return diffVal;

I think you are trying to use a loop to examine one character by one character in sBuffer1. But String let1 = String.valueOf(sBuffer1); gives you the entire string of sBuffer1.
What you need is String let1 = sBuffer1.substring(i, i + 1) to take a single character from sBuffer1 to check if it exists in sBuffer2.
For example:
public static StringBuffer diff(StringBuffer sBuffer1, StringBuffer sBuffer2) {
StringBuffer diffVal = new StringBuffer();
for (int i = 0; i < sBuffer1.length(); i++) {
String let1 = sBuffer1.substring(i, i + 1); // get the character from sBuffer1
if (sBuffer2.indexOf(let1) == -1) {
diffVal.append(let1); // append the character to the diff
}
}
return diffVal;
}

ok this might work, your logic was a little bit wrong, this code is straight forward. search for the character if it doesn't exist in the second string buffer add it to the result SF.
public StringBuffer diff(){
StringBuffer diffVal = new StringBuffer();//initialize before you use it.
for (int i =0; i < sBuffer1.length(); i++){
String let1 = String.valueOf(sBuffer1.charAt(i))//get the character at the ith position.
if (sBuffer2.indexOf(let1) == -1 ){
diffVal.append(let1);
}
}
return diffVal;
}

Try this.
StringBuilder diffVal= new StringBuilder();
StringBuffer sBuffer1 = new StringBuffer("abbad");//input 1
StringBuffer sBuffer2 = new StringBuffer("acca");//input 2, you can ignore if you have already passed/defined these
for (int i =0; i < sBuffer1.length(); i++){
if(i >= sBuffer2.length()){//handles difference in input string length
diffVal.append(sBuffer1.substring(i, sBuffer1.length()));
break;
}
if (sBuffer1.charAt(i) != sBuffer2.charAt(i)) {
diffVal.append(sBuffer1.charAt(i));
}
}
System.out.println(diffVal);// I am printing it here
the out put is : bbd
One recommendation here is use StringBuilder if you the strings you are using here are not required to be synchronized

Related

Why am I getting whitespaces in StringBuilder in Java?

I wrote a method that returns a rotated StringBuilder with a given key. However, although it is working fine, it's adding white spaces within the StringBuilder.
public static StringBuilder rotateCipher(String plain, int key) {
int keyTemp = key;
char[] rotatedChar = new char[plain.length()];
StringBuilder builder = new StringBuilder();
for (int i = 0; i < plain.length(); i++) {
rotatedChar[i] = plain.charAt(key);
key++;
if (key == plain.length()) {
builder.append(String.valueOf(rotatedChar));
builder.append(plain.substring(0, keyTemp + 1));
break;
}
}
return builder;
}
Output: nopqrstuvwxyz abcdefghijklmn
The reason for the whitespace is that the array rotatedChar does not have all it's elements filled. By default, a char[] contains only (char)0 elements.
When you call this method with the parameters "abcdefghijklmnopqrstuvwxyz", 13 then only the first 13 elements of rotatedChar get filled, then you hit the if-condition and break out of the loop. That means you have the remaining 13 elements left as 0s, which is a nonprintable character, so it appears as whitespace.
It's a bit hard to suggest which part to change here because as Gabe pointed out in the comments, the solution only requires 2 calls to substring.
If you really want to use loops, maybe this can be an approach:
for (int i = 0; i < plain.length(); i++) {
rotatedChar[i] = plain.charAt(key);
key++;
if (key == plain.length()) {
//this "restarts" taking chars from the beginning of the string
key = 0;
}
}
return String.valueOf(rotatedChar);

Best way to concatenate Strings in java(Time efficiency)

I checked many discutions about the best way to concatenate many string In Java.
As i understood Stringbuilder is more efficient than the + operator.
Unfortunantly My question is a litlle bit different.
Given the string :"AAAAA", how can we concatenate it with n times the char '_',knowing that the '_' has to come before the String "AAAAA"
if n is equal to 3 and str="AAAAA", the result has to be the String "___AAAAA"
String str = "AAAAA";
for (int i=0;i<100;i++){
str="_"+str;
}
In my program i have a Longs String , so i have to use the efficient way.
Thank you
EDIT1:
As I have read some Solutions I discovered that I asked for Only One Case , SO I arrived to this Solution that i think is good:
public class Concatenation {
public static void main(String[] args) {
//so str is the String that i want to modify
StringBuilder str = new StringBuilder("AAAAA");
//As suggested
StringBuilder space = new StringBuilder();
for (int i = 0; i < 3; i++) {
space.append("_");
}
//another for loop to concatenate different char and not only the '_'
for (int i = 0; i < 3; i++) {
char next = getTheNewchar();
space.append(next);
}
space.append(str);
str = space;
System.out.println(str);
}
public static char getTheNewchar(){
//normally i return a rondom char, but for the case of simplicity i return the same char
return 'A';
}
}
Best way to concatenate Strings in Java: You don't.... Strings are immutable in Java. Each time you concatenate, you generate a new Object. Use StringBuilder instead.
StringBuilder sb = new StringBuilder();
for (int i=0;i<100;i++){
sb.append("_");
}
sb.append("AAAAA");
String str = sb.toString();
Go to char array, alloting the right size, fill the array, and sum it up back into a string.
Can’t beat that.
public String concat(char c, int l, String string) {
int sl = string.length();
char[] buf = new char[sl + l];
int pos = 0;
for (int i = 0; i < l; i++) {
buf[pos++] = c;
}
for (int i = 0; i < sl; i++) {
buf[pos++] = string.charAt(i);
}
return String.valueOf(buf);
}
I'd do something like:
import java.util.Arrays;
...
int numUnderbars = 3;
char[] underbarArray = new char[numUnderbars];
Arrays.fill(underbarArray, '_');
String output = String.valueOf(underbarArray) + "AAAA";
but the reality is that any of the solutions presented would likely be trivially different in run time.
If you do not like to write for loop use
org.apache.commons.lang.StringUtils class repeat(str,n) method.
Your code will be shorter:
String str=new StringBuilder(StringUtils.repeat("_",n)).append("AAAAA").toString();
BTW:
Actual answer to the question is in the code of that repeat method.
when 1 or 2 characters need to be repeated it uses char array in the loop, otherwise it uses StringBuilder append solution.

how to delete duplicate character from a string

The problem asks me to write a method to delete the duplicate characters from the original string and return the new string.For example, the original string is abracadabra and the result should be abrcd.
I was thinking about using StringBuilder to delete the character, but something went wrong when I tried to run the code. can anyone help me fix it.
public static String eliminateDuplicates(String str){
String result = "";
StringBuilder strings = new StringBuilder(str);
for(int i = 0; i<str.length(); i++){
for(int j = 1; j<str.length();j++){
if(str.charAt(i)==str.charAt(j)){
strings.deleteCharAt(j);
}
}
}
result = strings.toString();
return result;
}
Try this.
public static String eliminateDuplicates(String str){
int[] uniq = str.codePoints().distinct().toArray();
return new String(uniq, 0, uniq.length);
}
Using #P.J's idea
public static String eliminateDuplicates(String str) {
HashSet<Character> hashSet = new HashSet();
//A hashSet is a collection that only adds unique elements.
char[] toCharArray = str.toCharArray();
for (char c : toCharArray) {
hashSet.add(c);
}
StringBuilder answer = new StringBuilder();
for (Character character : hashSet) {
answer.append(character);
}
return answer.toString();
}
Try this code, maybe your can optimize :
public static String eliminateDuplicates(String source) {
StringBuilder result = new StringBuilder();
for (int i = 0, sLength = source.length(); i < sLength; i++) {
char readyToAdd = source.charAt(i);
boolean add = true;
for (int j = 0; j < result.length(); j++) {
if (readyToAdd == result.charAt(j)) {
add = false;
break;
}
}
if (add) result.append(readyToAdd);
}
return result.toString();
}
The code in question is iterating over input string but using the index to delete characters from the string builder object.
Every time the string builder deletes the character it will reduce in size. So, your code will fail with IndexOutofBoundsException. Please add the entire stack trace of the exception in the question to confirm, if that's the case.
A better approach to deleting duplicates is to create another string by iterating over the input string and then copying only the unique characters to new string. The new string can then be returned as a result.
This will also have better time complexity of O(n*m)compared to current code which had time complexity of O(n*n)
Try this
public static String eliminateDuplicates(String str){
StringBuilder result = new StringBuilder();
BitSet bs=new BitSet(256);
char[] chars=str.toCharArray();
char getChar=0;
for(int i=0;i<chars.length;i++){
getChar=chars[i];
if(!bs.get(getChar)){
result.append(getChar);
bs.set(getChar);
}
}
return result.toString();
}

How to print String buffer lines from last to first order

I have requirement to print String buffer lines as last to first order.
Example :toString of Stringbuffer method is printing below output:
this
is
some
text
Desired output:
text
some
is
this
What you could do is to create an array, iterate over it.
String s = new String("this\nis\nsome\ntext");
String []tokens = s.split("\n");
for(int i = tokens.length - 1; i >= 0; --i)
System.out.println(tokens[i]);
StringBuffer s = new StringBuffer("this\nis\nsome\ntext");
String []tokens = s.toString().split("\n");
for(int i = tokens.length - 1; i >= 0; --i)
System.out.println(tokens[i]);
A better memory less approach would be.
StringBuffer s = new StringBuffer("this\nis\nsome\ntext");
String word = "";
for(int i = s.length() - 1; i >= 0; --i)
{
if(s.charAt(i) != '\n')
{
word = s.charAt(i) + word;
}
else{
System.out.println(word);
word = "";
}
}
if(!word.equals(""))
System.out.println(word);
StringBuffer is a final class so you cannot extend it and override its toString() method to achieve what you want to do. You will have to handle it in your code.
you will have to do something like this :
public class Reverse {
public static void main(String[] args) {
// TODO Auto-generated method stub
StringBuffer s =new StringBuffer();
s.append("this\nis\nsome\ntext");
String[] rev = s.toString().split("\n");
for(int i=rev.length-1;i>=0;i--) {
System.out.println(rev[i]);
}
}
}
o/p :
text
some
is
this
Hope that helps
StringBuffer does not, by itself, have the capacity to return the lines the way you want them. You can either get the whole string from the buffer and use string.split("\n") to split it into an array, which you can then iterate over back to front, or create a class of your own that provides a function that handles such an operation
This should probably do it:
String[] lines = myStringBuffer.toString().split(System.lineSeparator()); //or use any other character for splitting
for(int i=lines.length; i>0; i--) {
System.out.println(lines[i-1]);
}
StringBuffer or String also has a lastIndexOf.
StringBuffer buf = new StringBuffer("this\nis\nsome\ntext");
final String EOL = "\n"; // Or "\r\n" or even "\u0085".
for (int pos = buf.length(); pos > 0; ) {
int before = buf.lastIndexOf(EOL, pos);
before = before == -1 ? 0 : before + EOL.length();
String line = buf.substring(before, pos);
System.out.println(buf);
pos = before - EOL.length();
}
Note: StringBuilder is better.

Java: how do icheck if a certain character is within a string, then print out the position it is in relative to the string?

What I am trying to do, is create a method, that has a string and a character as parameters, the method then takes the string and searches for the given character. If the string contains that character, it returns an array of integers of where the character showed up. Here is what I have so far:
public class Sheet {
public static void main(String[] args) {
String string = "bbnnbb";
String complete = null;
//*******
for(int i = 0; i < string.length(); i++){
complete = StringSearch(string,'n').toString();
}
//********
}
public static int[] StringSearch(String string, char lookfor) {
int[]num = new int[string.length()];
for(int i = 0; i < num.length; i++){
if(string.charAt(i)== lookfor){
num[i] = i;
}
}
return num;
}
}
The method works fine, and returns this:
0
0
2
3
0
0
What I am trying to do, is make those into 1 string so it would look like this "002300".
Is there any possible way of doing this? I have tried to do it in the starred area of the code, but I have had no success.
just do
StringBuffer strBuff = new StringBuffer();
for(int i = 0; i<str.length(); i++)
{
if(str.charAt(i) == reqChar)
{
strBuff.append(str.charAt(i));
}
else
{
strBuff.append('0');
}
}
return str.toString();
Just add the result to the existing string with the += operator
String complete = "";
for(...)
complete += StringSearch(string,'n').toString();
I would just use java's regex library, that way it's more flexible (eg if you want to look for more than just a single character). Plus it's highly optimized.
StringBuilder positions = "";
Pattern pattern = Pattern.compile(string);
Matcher matcher = pattern.matcher(lookfor);
while(matcher.find()){
positions.append(matcher.start());
}
return positions;
Updated with StringBuilder for better practices.
public static String StringSearch(String string, char lookfor) {
StringBuilder sb = new StringBuilder();
for(int i = 0; i < string.length; i++){
if(string.charAt(i) == lookfor)
sb.append(i);
else
sb.append("0");
}
return sb.toString();
}
Then you can just call it once, without a for loop. Not sure why you call it for every character in the string.
complete = StringSearch(string,'n');

Categories