I'm trying to make a code that deletes the repeated characters. For example - if we have a string "aabacdc", we want to make it as "abd". If the character exists twice in the string, then we delete both characters as we did in the above example. The 'a' occurs 3 times in our string, so we just deleted the 2 a and left 1 remaining.
What I'm trying to do in this code is use two nested for loops - first for loop to compare the first character with the other characters. If the character has a duplicate in the string, then just delete both the characters. How can I fix this code?
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str2 = input.nextLine();
StringBuilder str = new StringBuilder(str2);
for (int k = 0; k < str.length() - 1; k++) {
for (int i = 1; i < str.length() - 1; i++) {
if (str.charAt(k) == str.charAt(i)) {
str.deleteCharAt(k);
str.deleteCharAt(i);
}
}
}
System.out.println(str);
}
My interpretation of what you're trying to do based on your expected output is that you want to remove characters from the string 1 pair at a time. So if there is an odd number of a character in the string, 1 should remain, and if there's an even number 0 should remain.
Any time you're removing elements from a structure while you're iterating by index, you need to loop over the structure backwards, so that the index values don't shift as you delete elements. This means you should only delete elements which the outer loop is currently at, or has already seen (i.e. only delete elements at indexes >= i).
Scanner input = new Scanner(System.in);
String str = input.nextLine();
StringBuilder sb = new StringBuilder(str);
for (int i = sb.length() - 2; i >= 0; i--) {
for (int j = i + 1; j < sb.length(); j++) {
if (sb.charAt(i) == sb.charAt(j)) {
sb.deleteCharAt(j);
sb.deleteCharAt(i);
break;
}
}
}
System.out.println(sb);
Ideone Demo
Related
I have reversed the string and have a for loop to iterate through the reversed string.
I am counting characters and I know I have a logic flaw, but I cannot pinpoint why I am having this issue.
The solution needs to return the length of the last word in the string.
My first thought was to iterate through the string backward (I don't know why I decided to create a new string, I should have just iterated through it by decrementing my for loop from the end of the string).
But the logic should be the same from that point for my second for loop.
My logic is basically to try to count characters that aren't whitespace in the last word, and then when the count variable has a value, as well as the next whitespace after the count has counted the characters of the last word.
class Solution {
public int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
for(int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
reversed += ch;
}
for(int i = 0; i < reversed.length(); i++) {
if(!Character.isWhitespace(reversed.charAt(i))) {
count++;
if(count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
}
return count;
}
}
Maybe try this,
public int lengthOfLastWord(String s) {
String [] arr = s.trim().split(" ");
return arr[arr.length-1].length();
}
Another option would be to use index of last space and calculate length from it:
public int lengthOfLastWord(String string) {
int whiteSpaceIndex = string.lastIndexOf(" ");
if (whiteSpaceIndex == -1) {
return string.length();
}
int lastIndex = string.length() - 1;
return lastIndex - whiteSpaceIndex;
}
String.lastIndexOf() finds the start index of the last occurence of the specified string. -1 means the string was not found, in which case we have a single word and length of the entire string is what we need. Otherwise means we have index of the last space and we can calculate last word length using lastIndexInWord - lastSpaceIndex.
There are lots of ways to achieve that. The most efficient approach is to determine the index of the last white space followed by a letter.
It could be done by iterating over indexes of the given string (reminder: String maintains an array of bytes internally) or simply by invoking method lastIndexOf().
Keeping in mind that the length of a string that could be encountered at runtime is limited to Integer.MAX_VALUE, it'll not be a performance-wise solution to allocate in memory an array, produced as a result of splitting of this lengthy string, when only the length of a single element is required.
The code below demonstrates how to address this problem with Stream IPA and a usual for loop.
The logic of the stream:
Create an IntStream that iterates over the indexes of the given string, starting from the last.
Discard all non-alphabetic symbols at the end of the string with dropWhile().
Then retain all letters until the first non-alphabetic symbol encountered by using takeWhile().
Get the count of element in the stream.
Stream-based solution:
public static int getLastWordLength(String source) {
return (int) IntStream.iterate(source.length() - 1, i -> i >= 0, i -> --i)
.map(source::charAt)
.dropWhile(ch -> !Character.isLetter(ch))
.takeWhile(Character::isLetter)
.count();
}
If your choice is a loop there's no need to reverse the string. You can start iteration from the last index, determine the values of the end and start and return the difference.
Just in case, if you need to reverse a string that is the most simple and efficient way:
new StringBuilder(source).reverse().toString();
Iterative solution:
public static int getLastWordLength(String source) {
int end = -1; // initialized with illegal index
int start = 0;
for (int i = source.length() - 1; i >= 0; i--) {
if (Character.isLetter(source.charAt(i)) && end == -1) {
end = i;
}
if (Character.isWhitespace(source.charAt(i)) && end != -1) {
start = i;
break;
}
}
return end == -1 ? 0 : end - start;
}
main()
public static void main(String[] args) {
System.out.println(getLastWord("Humpty Dumpty sat on a wall % _ (&)"));
}
output
4 - last word is "wall"
Firstly, as you have mentioned, your reverse string formed is just a copy of your original string. To rectify that,
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
Secondly, the second if condition is inside your first if condition. That is why, it will never break ( because you are first checking if character is whitespace, if it is, then you are not going inside the if statement, thus your second condition of your inner if loop will never be satisfied).
public class HW5 {
public static void main(String[] args) {
String s = "My name is Mathew";
int count = lengthOfLastWord(s);
System.out.println(count);
}
public static int lengthOfLastWord(String s) {
int count = 0;
int countWhite = 0;
char ch;
String reversed = "";
System.out.println("original string is----" + s);
for (int i = s.length() - 1; i >= 0; i--) {
ch = s.charAt(i);
reversed += ch;
}
System.out.println("reversed string is----" + reversed);
for (int i = 0; i < reversed.length(); i++) {
if (!Character.isWhitespace(reversed.charAt(i)))
count++;
if (count > 1 && Character.isWhitespace(reversed.charAt(i)) == true) {
break;
}
}
return count;
}
}
=
and the output is :
original string is----My name is Mathew
reversed string is----wehtaM si eman yM
6
Another way to go about is : you use the inbuilt function split which returns an array of string and then return the count of last string in the array.
I want get a String like this "SsjAasdLlswAasdMm"
and print a String like this "salam"
(print characters as String that are next to a Capital)
I wrote this :
import java.util.Scanner;
public class Temp {
public static void main(String[] args) {
char[] capitalalphabet = new char[]{'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
Scanner input = new Scanner(System.in);
String s1 = input.next();
StringBuffer s2 = new StringBuffer();
for (int i=0 ; i < s1.length() ; i++) {
for (int j = 0; j < capitalalphabet.length; j++) {
if (s1.charAt(i) == capitalalphabet[j]){
int k = 0 ;
s2.setCharAt(k , s1.charAt(i+1));
k++;
}
}
}
System.out.println(s2);
}
}
and i got this error :
SAhfdsdEDsa
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.StringBuffer.setCharAt(StringBuffer.java:257)
at Temp.main(Temp.java:14)
It happens at this line:
s2.setCharAt(k, s1.charAt(i+1));
According to the documentation:
Throws:
StringIndexOutOfBoundsException - if start is less than zero, or greater than the length of this object.
Since your s2 string is empty (its length is 0), you're exceeding the bounds when you try to add to it.
Also, since your k variable is always initialized to zero right before the setChatAt method, and it's only defined inside the if-statement block, you'll always be setting at index 0, even if you could.
I'd suggest you just simply try to use StringBuilder instead, as well as discard the messy loop of captial letters - their ASCII code is sequential, you could simply ask if character is in range:
for (int i=0 ; i < s1.length()-1; i++) {
char c = s1.charAt(i);
if (c >= 'A' && c <= 'Z') {
s2.append(s1.charAt(i+1));
}
}
System.out.println(s2);
Note that the loop scans until the index before last, since it might access the next index (and since there's no need to check the last character - it cannot be followed by anything, capital or otherwise).
Note you could also replace the if condition with Character.isUpperCase(c) which is more readable and elegant.
Given a non-empty string str like "Code" print a string like "CCoCodCode". Where at each index in the string you have to reprint the string up to that index.
I know there is DEFINITELY something wrong with this code that I wrote because the answer should be CCoCodCode, but instead it's giving me the alphabet! I don't know how I should change it.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String str = scan.next();
int x = str.length();
for(char i = str.charAt(0); i <= str.charAt(x-1); i++)
{
System.out.print(i);
}
}
The char datatype can be treated as a number; you can increment it and manipulate it as a number.
What you really want is successive substrings of str to be printed. Loop over an int that will represent the ending position of the substring to be printed.
for (int i = 0; i < str.length(); i++)
{
System.out.print(str.substring(0, i + 1));
}
The end index argument to substring is exclusive, which is why I added 1.
Let's say that str is "Code". We can perform some mental substitutions to see what happens to your loop.
str is "Code"
x is 4
str.charAt(0) is 'C'
str.charAt(x-1) is 'e'
Making these substitutions, your loop is:
for(char i = 'C'; i <= 'e'; i++)
{
System.out.print(i);
}
Does this help you see the problem? I would think you'd have a loop from 0 to 3, not from 'C' to 'e'...
Many ways to get it done, suppose we have the input from user stored in a string named "c"... then...
String c = "Code";
for (int i = 0; i < c.length(); i++) {
System.out.print(c.substring(0, i));
}
System.out.print(c);
And this will print the sequence you are looking for.
It is outputting the alphabet because you are printing the counter instead of the characters in the string!
As it is, the first iteration of the for loop will set i to the first character, print that, then the operation i++ will increment i by one. Wait, so if the first character is "C", so i = 'C', what is i++?
Well it turns out characters can be represented by numbers. For example, 'C' has a value of 67. So incrementing it makes it 68, which represents 'D'. So if you run the loop on "Code", it will increment your counter 4 times, giving "CDEF". If you run on "Codecodecode", that will make the loop run 12 times, giving "CDEFGHIJKLMN".
What you really want is to loop through the string by its index instead:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str = scan.next();
int length = str.length();
for (int i = 0; i < length; i++) {
System.out.print(str.substring(0, i + 1));
}
}
Hello I am having trouble implementing this function
Function:
Decompress the String s. Character in the string is preceded by a number. The number tells you how many times to repeat the letter. return a new string.
"3d1v0m" becomes "dddv"
I realize my code is incorrect thus far. I am unsure on how to fix it.
My code thus far is :
int start = 0;
for(int j = 0; j < s.length(); j++){
if (s.isDigit(charAt(s.indexOf(j)) == true){
Integer.parseInt(s.substring(0, s.index(j))
Assuming the input is in correct format, the following can be a simple code using for loop. Of course this is not a stylish code and you may write more concise and functional style code using Commons Lang or Guava.
StringBuilder builder = new StringBuilder();
for (int i = 0; i < s.length(); i += 2) {
final int n = Character.getNumericValue(s.charAt(i));
for (int j = 0; j < n; j++) {
builder.append(s.charAt(i + 1));
}
}
System.out.println(builder.toString());
Here is a solution you may like to use that uses Regex:
String query = "3d1v0m";
StringBuilder result = new StringBuilder();
String[] digitsA = query.split("\\D+");
String[] letterA = query.split("[0-9]+");
for (int arrIndex = 0; arrIndex < digitsA.length; arrIndex++)
{
for (int count = 0; count < Integer.parseInt(digitsA[arrIndex]); count++)
{
result.append(letterA[arrIndex + 1]);
}
}
System.out.println(result);
Output
dddv
This solution is scalable to support more than 1 digit numbers and more than 1 letter patterns.
i.e.
Input
3vs1a10m
Output
vsvsvsammmmmmmmmm
Though Nami's answer is terse and good. I'm still adding my solution for variety, built as a static method, which does not use a nested For loop, instead, it uses a While loop. And, it requires that the input string has even number of characters and every odd positioned character in the compressed string is a number.
public static String decompress_string(String compressed_string)
{
String decompressed_string = "";
for(int i=0; i<compressed_string.length(); i = i+2) //Skip by 2 characters in the compressed string
{
if(compressed_string.substring(i, i+1).matches("\\d")) //Check for a number at odd positions
{
int reps = Integer.parseInt(compressed_string.substring(i, i+1)); //Take the first number
String character = compressed_string.substring(i+1, i+2); //Take the next character in sequence
int count = 1;
while(count<=reps)//check if at least one repetition is required
{
decompressed_string = decompressed_string + character; //append the character to end of string
count++;
};
}
else
{
//In case the first character of the code pair is not a number
//Or when the string has uneven number of characters
return("Incorrect compressed string!!");
}
}
return decompressed_string;
}
I'm trying to write a program which accepts a word in lowercase, converts it into uppercase and changes the vowels in the word to the next alphabet. So far, I've done this:
import java.util.*;
class prg11
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word in lowercase.");
String word = sc.next();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<=length; i++)
{
ch[i] = word.charAt(i);
if("aeiou".indexOf(ch[i]) == 0)
{
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
The code compiles fine. But, when I run the program and enter a word, say 'hey', the word is printed in uppercase only. The vowels in it (in this case, 'e'), do not get changed to the next alphabet.
How do I resolve this? TIA.
Need to change three places, according to the code in the question.
word = word.toUpperCase();
int length = word.length();
// yours: char ch[] = new char[length + 1];
// resulting array needs to be as same length as the original word
// if not, there will be array index out of bound issues
char ch[] = new char[length];
// yours: for (int i = 0; i<=length; i++)
// need to go through valid indexes of the array - 0 to length-1
for (int i = 0; i < length; i++) {
ch[i] = word.charAt(i);
// yours: if ("aeiou".indexOf(ch[i]) == 0) {
// two problems when used like that
// 1. indexOf() methods are all case-sensitive
// since you've uppercased your word, need to use AEIOU
// 2. indexOf() returns the index of the given character
// which would be >= 0 when that character exist inside the string
// or -1 if it does not exist
// so need to see if the returned value represents any valid index, not just 0
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Here's a little concise version. Note the changes I've done.
String word = sc.next().toUpperCase();
char ch[] = word.toCharArray();
for (int i = 0; i < ch.length; i++) {
if ("AEIOU".indexOf(ch[i]) >= 0) {
ch[i] += 1;
}
}
Java doc of indexOf().
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character.
If a character with value ch occurs in the character sequence represented by this String object,
then the index (in Unicode code units) of the first such occurrence is returned.
For values of ch in the range from 0 to 0xFFFF (inclusive), this is the smallest value k such that:
this.charAt(k) == ch
is true. For other values of ch, it is the smallest value k such that:
this.codePointAt(k) == ch
is true. In either case, if no such character occurs in this string, then -1 is returned.
Parameters:
ch - a character (Unicode code point).
Returns:
the index of the first occurrence of the character in the character sequence represented by this object,
or -1 if the character does not occur.
I think this should do it, let me know if it doesn't
public class prg11 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a word.");
String word = sc.next();
sc.close();
word = word.toUpperCase();
int length = word.length();
char ch[] = new char[length+1];
for (int i = 0; i<length; i++) {
ch[i] = word.charAt(i);
if("AEIOU".indexOf(ch[i]) > -1) {
ch[i]+=1;
}
}
String str = new String(ch);
System.out.println(str);
}
}
Let me know if it works.
Happy coding ;) -Charlie
Use:
for (int i = 0; i<length; i++)
instead as the last index is length-1.
use for (int i = 0; i<=length-1; i++) instead of for (int i = 0; i<=length; i++) and if("AEIOU".indexOf(ch[i]) != -1) instead of if("aeiou".indexOf(ch[i]) == 0)
reason
1.array index starts from 0 that's why length-1
2. As you already made your string in upper case so check condition on "AEIOU"
3. every non-vowel character will return -1 so use if("AEIOU".indexOf(ch[i]) != -1)
"aeiou".indexOf(ch[i]) == 0 will only match 'a' characters (since that is the character at index 0). You should be looking for any index that is greater than -1. Additionally, since you've already converted the string to uppercase, you should be checking against "AEIOU" instead of "aeiou".