I know that it exists, but my teacher wants me to do it manuallyI am trying to reverse my a stringBuilder so that the characters I have inside go in reverse order, sometimes the stringBuilder is of a single character, that is why as you can see there is an if that indicates when the characters of the stringBuilder should be turned over. This is what I have at the moment.
if ( sB.length ()> 1) {
for (int i = sB.length () - 1; i> = 0; i--) {
sB.append().charAt(i);
sB.deleteCharAt (i);
}
}
I know sB.reverse() exists, but my teacher wants me to do it manually and how you can see i don't know how to implement this two method's at once. If anyone can help me please. Thanks!
then in that case use this
StringBuilder str = new StringBuilder();
str.append("yourstring");
for(int i = str.length()-1 ; i>=0; i--)
{
str.append(str.charAt(i)).deleteCharAt(i);
}
if you want to reverse your string why dont you use
StringBuilder str = new StringBuilder();
str.append("yourstring");
str.reverse();
swap it two by two if you arent allowed to use reverse() method
StringBuilder sb = new StringBuilder("abcde");
for (int i = 0; i < sb.length()/2; i++) {
char tmp = sb.charAt(i);
sb.setCharAt(i, sb.charAt(sb.length() - 1 - i));
sb.setCharAt(sb.length() - 1 - i, tmp);
}
System.out.println(sb.toString());
Use this code to do it manually.
public class Reverse {
public static void main(String args []) {
String rev = "This should be reversed";
StringBuilder stb = new StringBuilder();
int i = rev.length()-1;
while (i != -1) {
char re = rev.charAt(i);
stb.append(re);
i--;
}
System.out.println(stb);
}
}
Related
process_str(StringBuilder copy, List<Integer> idxList) {
for(int i = 0; i < idxList.size(); ++i) {
int pos = idxList.get(i);
copy.setCharAt(pos, '$');
}
StringBuilder output = new StringBuilder();
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if(ch != '$')
output.append(ch);
}
return output.toString();
}
Constraint - $ does not appear in the input string.
Is there a simpler way to do this?
You can remove the first loop like this:
process_str(StringBuilder copy, List<Integer> idxList) {
StringBuilder output = new StringBuilder();
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if (idxList.contains(i))
output.append(ch);
}
return output.toString();
}
The overall time complexity might be different depending on what type of List you use.
I've read that your solution has a constraint where the original string does not contain a dollar sign, but you could keep your code more generalized if you don't impose said constraint.
If your goal is to keep it as concise as possible you could use streams, strictly a sequential stream, with a stateful lambda:
String str = "Hello my new world!";
List<Integer> idxList = new ArrayList<>(List.of(3, 5, 6));
StringBuilder strBld = new StringBuilder();
IntStream.range(0, str.length()).boxed().forEach(i -> {
if (!idxList.contains(i)) strBld.append(str.charAt(i));
});
Solution similar to rikyeah but avoiding the complexity of contains.
Here we first sort the input idxList in order to have the indices in ascendant order, then we create the output StringBuilder with a initial capacity computed from the length of the input StringBuilder and the number of index to remove. Finally we browse the input StringBuilder and avoid the copy when we reach the next index to remove.
public String process_str(StringBuilder copy, List<Integer> idxList) {
List<Integer> sortedIndices = new ArrayList<>(idxList);
Collections.sort(sortedIndices);
Iterator<Integer> idxIterator = sortedIndices.iterator();
int currIdx;
if (idxIterator.hasNext()) {
currIdx = idxIterator.next();
} else {
currIdx = copy.length();
}
StringBuilder output = new StringBuilder(copy.length() - idxList.size());
for(int i = 0; i < copy.length(); ++i) {
char ch = copy.charAt(i);
if (i != currIdx) {
output.append(ch);
} else if (idxIterator.hasNext()) {
currIdx = idxIterator.next();
}
}
return output.toString();
}
I'm trying to remove duplicates in a string but I'm not sure why my algorithm's wrong. It's giving me an output of baa instead of bans which's the correct output.
During my attempt to debug, I tried switching the i to j inside sb.deleteCharAt(); but that gave me a Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5 error.
What am I doing wrong and how can I fix this?
Here's my code:
public static void removeDuplicate(String s) {
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < s.length(); i++) {
for(int j = i + 1; j < s.length(); j++) {
if(s.charAt(i) == s.charAt(j)) {
sb.deleteCharAt(i);
}
}
}
System.out.print("Duplicates have been, the resulting string is => " + sb);
}
public static void main(String[] args) {
String s = "bananas";
removeDuplicate(s);
}
There are a couple of things that are wrong. You should make the comparison with string builder in your loops, not with string itself, as it changes. Second, you're using wrong index in removal. Here's the correct program:
public static void removeDuplicate(String s) {
StringBuilder sb = new StringBuilder(s);
for(int i = 0; i < sb.length(); i++) {
for(int j = i + 1; j < sb.length(); j++) {
if(sb.charAt(i) == sb.charAt(j)) {
sb.deleteCharAt(j);
}
}
}
System.out.print("Duplicates have been, the resulting string is => " + sb);
}
public static void main(String[] args) {
String s = "bananas";
removeDuplicate(s);
}
The output is:
Duplicates have been, the resulting string is => bans
You can use distinct() :
StringBuilder sb = new StringBuilder();
yourstr.chars().distinct().forEach(c -> sb.append((char) c));
Best
Well, deleting elements from a collection while loop through it is a bad idea, because it can cause wrong logic base on index changes.
Just put some special case like "baaana", your solution will fail easily because when you trying to found "a" at index 2, you remove it and skip comparing with the "actual" index 3 because its index is decreased to 2 after removing.
And another thing you should know. In Java, String is immutable, that means when you change a string, you actually assign the variable with the new one. So those function should return a new String instead of modifying input.
With this type of problem, i suggest you should use a hash data type to memorize the distinct elements, so you can solve this with an O(n) time complexity.
public static String removeDuplicate(String s) {
StringBuilder sb = new StringBuilder();
Set<Character> metChars = new HashSet<>();
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(!metChars.contains(c)) {
sb.append(c);
metChars.add(c);
}
}
return sb.toString();
}
Basically, when you remove a character in your StringBuilder, you effectively change the indexes of all further characters.
In your example bananas, if you remove the second a (pos 3 since we start at 0), you get the string bannas. Then, when you want to remove the 3rd a of bananas, at pos 5, you end up removing the s.
as mentioned in the title, I got an error in each line inside for loop which says (variable expected) and this is my code
String s = "ABC";
String t = "DEFGH";
String merge = "";
// merge should looks like "ADBECFGH"
int i = 0;
for (; i < s.length(); i=i+2) {
merge.charAt(i) = s.charAt(i/2);
merge.charAt(i+1) = t.charAt(i/2);
}
for (; i < t.length()+s.length() ; i++) {
merge.charAt(i) = t.charAt(i-s.length());
}
am trying to use same technique with arrays which I think its very effective.
If you like take one letter from first string and then from other try this:
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge += String.valueOf(s.charAt(i));
}
if (i < t.length()) {
merge += String.valueOf(t.charAt(i));
}
}
This is condition that let you iterate till longer String finish
i < s.length() || i < t.length()
Another one, since you are manipulating Strings inside a loop, it is better to use StringBuilder instead of String.
String s = "ABC";
String t = "DEFGH";
StringBuilder merge = new StringBuilder();
for (int i = 0; i < s.length() || i < t.length(); i++) {
if (i < s.length()) {
merge.append(s.charAt(i));
}
if (i < t.length()) {
merge.append(t.charAt(i));
}
}
System.out.println(merge.toString());
The method charAt(int index) returns the character at the specified index(IT IS A GETTER NOT A SETTER). You cannot use it as
merge.charAt(i) = s.charAt(i/2)
one of the easiest ways to perform such operation is to use string operation such as concatination as shown in the below example
s="abc";
t="def";
System.out.print(s.concat(t));
You could simply use the .concact() method without using the for loop:
so your code would look like:
merge = s.concat(t);
try this : concatenate two string without inbuilt method and without + operator.
public static void main(String[] args) {
String s = "ABC";
String s1 = "DEF";
String merge = "";
char[]ch = new char[120];
for(int i=0;i<s.length();i++) {
ch[i] = s.charAt(i);
}
for(int i = 0;i<s1.length();i++) {
ch[s.length()+i] = s1.charAt(i);
}
System.out.println(ch);
}
CharacterIterator a = new StringCharacterIterator("haaaaallo");
CharacterIterator b = new StringCharacterIterator("12345");
StringBuilder output = new StringBuilder();
if(a.getEndIndex() < b.getEndIndex()) { //true -> swap a and b
CharacterIterator holder = a;
a = b;
b = holder;
}
while (a.current() != CharacterIterator.DONE) {
output.append(a.current());
while (b.current() != CharacterIterator.DONE) {
output.append(b.current());
break;
}
a.next();
b.next();
}
System.out.println(output.toString()); //h1a2a3a4a5allo
To show "the manual way". The used Strings can be any size.
I would go with #Bartek's answer its simple and easy to remember..
the complicated way to achieve this would be
String a = "abcdefgh";
String b = "ijklmnopqrst";
int i = 0;
StringBuilder merge = new StringBuilder();
for (; i < a.length() && i < b.length(); i++) {
merge.append(a.charAt(i)).append(b.charAt(i));
}
if (i < a.length())
merge.append(a.substring(i));
if (i < b.length())
merge.append(b.substring(i));
Only to avoid having if conditions inside the for loop.. (optimal only in case of large strings, strings of vastly different lengths)
I want to divide the following message by 10 character. I want to append every part into StringBuilder object.
04421,1,13,S,312|4000004130,1;4000000491,1;4000005240,1;4000005789,2;4000004978,2;4000004934,2;4000004936,1;4000000569,2;4000005400,1;4000000;4000004934,2;
I have done the following solution :
if(getMsgOtherPart(message) != null){
System.out.println("part message::"+getMsgOtherPart(message));
String newMessage = getMsgOtherPart(message) ;
int len = newMessage.length();
System.out.println("len::"+len);
int firstIndex = 0;
int limit = 10;
int lastIndex = 10;
int count = 0;
StringBuilder sb = new StringBuilder();
String completeMessage = null;
for(int i = 0; i <= len;i++){
count++;
if( count == limit && lastIndex < len){
sb.append(getSmsUniqueHeader());
sb.append(newMessage.substring(firstIndex,lastIndex));
sb.append("#");
sb.append("\n");
firstIndex = lastIndex;
lastIndex = firstIndex + limit;
count = 0;
} else if(count < limit && i == len) {
System.out.println("lastIndex:: "+lastIndex);
sb.append(getSmsUniqueHeader());
sb.append(newMessage.substring(lastIndex-10));
sb.append("#");
}
}
completeMessage = sb.toString();
System.out.println("message::\n"+completeMessage);
}
I am getting output:
message::
$04421,1,13#
$,S,312|400#
$0004130,1;#
$4000000491#
$;400000540#
$0,1;400000#
$0;40000000#
$63,1;40000#
$00076,1;40#
$00000776,2#
$;400000078#
$8,2;400000#
------------
$0;#
Please let me know to optimize my solution.
I had done this kind of thing in one of my project and here is the function i used, which return the List but you can modify it and use StringBuilder.
public List<String> splitStringEqually(String txtStr, int subStringSize) {
List<String> splittedStringList = new ArrayList<String>();
for (int start = 0; start < txtStr.length(); start += subStringSize) {
splittedStringList.add(txtStr.substring(start, Math.min(txtStr.length(), start + subStringSize)));
}
return splittedStringList;
}
You can use Google's Guava library and use the Splitter class for this.
StringBuilder sb=new StringBuilder();
for(String s: Splitter.fixedLength(10).split(message)){
sb.append(s);
sb.append("#\n");
}
System.out.println(sb.toString());
String is maintained as char array internally. You can get the copy of that char array using message.toCharArray() and using a simple loop or java 8 streams pick elements in chunks of 10 and do whatever stuff you need to do.
Basing heavily on Rajen Raiyarela's answer and addressing the specific request from the OP, the code may look like this (upvote that one, not this one please!):
public String splitStringEqually(String txtStr, int subStringSize) {
// Start off with the header
StringBuilder sb = new StringBuilder("message::\n");
int len = txtStr.length();
for (int start = 0; start < len; start += subStringSize) {
sb.append("$");
// Copy the next 10 characters, or less if at end of string
// Does not use txtStr.substring() as that creates an
// unnecessary temporary string
sb.append(txtStr, start, Math.min(len, start + subStringSize));
sb.append("#\n");
}
return sb.toString();
}
This can be called with simply:
String completeMessage = splitStringEqually(newMessage, limit);
Cant seem to get this to work. trying to get it to read backwards like a mirror without using the buffer class.
public static void main(String[] args) {
Scanner keyboard = new Scanner(System. in);
System.out.println("Enter a phrase:");
String phrase = keyboard.nextLine();
String Rphrase;
int n = phrase.length();
int r = 0;
do{
n--; r++;
Rphrase[r] = phrase[n];
}while(n >= 0);
System.out.println(Rphrase);
I have provided 4 ways of getting the output of the String reversed.
Option 1:
Just iterate the String backwards.
for (int i=phrase.length()-1; i>-1; i--) {
System.out.print(foo.charAt(i));
}
Option 2:
If you would like to put it in the other buffer you can do:
char[] buffer = new char[phrase.length()];
index = 0;
for (int i=phrase.length()-1; i>-1; i--) {
buffer[index++] = foo.charAt(i);
}
Option 3:
You said you didnt want to use the buffer class (which I think you're referring to StringBuffer so I'm assuming you dont want to use StringBuilder either) so here is how you can do it strictly with Strings (which is rather inefficient, because a new String is constructed each iteration):
String foo = "";
for (int i=phrase.length()-1; i>-1; i--) {
foo += foo.charAt(i);
}
Option 4:
A most likely more efficient way of doing this though, is by using StringBuilder:
StringBuilder sb = new StringBuilder(foo.length());
for (int i=foo.length()-1; i>-1; i--) {
sb.append(foo.charAt(i));
}
String reverse = sb.toString();
OR
Refer to this for very simple String reversal with a StringBuilder:
Reverse a string in Java
Try:
public static void main(String[] args) {
Scanner keyboard = new Scanner(System. in);
System.out.println("Enter a phrase:");
String phrase = keyboard.nextLine();
String rPhrase = "";
for (int i = phrase.length() - 1; i >= 0; i--)
rPhrase += phrase.charAt(i);
System.out.println(rPhrase);
}
This is what you need.
String reverse = "";
String toReverse = "hello";
for(int i = 0; i<toReverse.length();i++){
reverse += toReverse.substring(i,i+1);
}
System.out.println(reverse);
Some hints, rather than a complete solution...
Your loop will run for one more iteration when n = 0, which will lead to trying to access index -1. So perhaps try n > 0 as your condition.
And what would happen if the string is empty? It would also try to access index -1, before ever getting to the loop. Perhaps you should put the condition at the beginning.
String doesn't support the [] operator - try:
Rphrase += phrase.charAt(n);
In which case you may as well get rid of r.
you have to make a decrement so it can read its value back to front
for (int i = name.length() - 1, j = 0; i >= 0; i--, j++) {
newName[j] = name.charAt(i); enter code here
}
System.out.println(newName);
}
Simply use StringBuilder.reverse
str = new StringBuilder(str).reverse().toString();