I have written this algorithm to determine if a string has all unique characters, but its giving me some errors. Can anyone help me with improving the code.
It is giving me the error that I am duplicating the uniquechar1 method but I am passing it to an if statement.
package nospacesinstrings;
import java.util.Scanner;
public class uniquechar {
public static boolean uniquechar1(String s) {
if (s == null || s.length() > 0 ) {
return false;
}
for (int i = 0 ;i < s.length();i++) {
for (int j = s.length() ;j > 0;j--) {
if (i == j)
return false;
else
return true;
}
}
}
public static void main(String[] args) {
String s ;
System.out.println("Enter the string ");
Scanner in = new Scanner(System.in);
s = in.nextLine();
if (uniquechar1(s) == true) {
System.out.println("String has all the unique characters ");
} else {
System.out.println("String does not have all the unique characters ");
}
}
}
Your check at the top looks backwards. I think you meant to put s.length() < 1 instead of s.length() > 0
You also are returning a value before you have finished iterating over your string. You should only return true if you iteration through the complete string without returning false
Also, your double loop will always end up comparing each character to itself so the method will return false. To do it using a for each loop, you need to stop before you get to the currently checked index.
for (int i = 0 ;i < s.length();i++){
for (int j = s.length() ;j > i;j--){
if (i == j )
{return false ;}
}
return true;
you could also avoid traversing twice down the string by collecting characters as you go. Something like this:
Stack<char> stack = new Stack<char>();
for (int i = 0 ;i < s.length();i++){
if (stack.Contains(s[i]))
{return false ;}
stack.Push(s[i]);
}
return true ;
Lastly, if you should research character comparison. Are you looking to fail if any two any character even if they are different cases (i.e. A == a or A != a)?
This algorithm should work. I'm assuming there are no numbers in the string. (Edited to correct code).
public static boolean uniquechar1(String s)
{
if (s == null || s.length() == 0 )
return true;
// make sure no letter in alphabet occurs twice in the string.
boolean[] letters = new boolean[26];
s = s.toUpperCase();
s = s.replaceAll(" ", "");
for (int i = 0; i < s.length(); i++)
{
char ch = s.charAt(i);
ch = (char) (ch - 'A');
if (letters[ch] == true)
return false;
else
letters[ch] = true;
}
return true;
}
Here is a tester method.
public static void main(String[] args)
{
System.out.println( uniquechar1("Hello World!") );
System.out.println( uniquechar1("A A") );
System.out.println( uniquechar1("ABC") );
}
Outputs:
false
false
true
Related
I am trying to convert this Python Solution in Java. For some reason, my Java Solution is not working. How can this be done correctly?
https://leetcode.com/problems/decode-string/description/
Given an encoded string, return its decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer.
You may assume that the input string is always valid; there are no extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there will not be input like 3a or 2[4].
The test cases are generated so that the length of the output will never exceed 105.
Example 1:
Input: s = "3[a]2[bc]"
Output: "aaabcbc"
Example 2:
Input: s = "3[a2[c]]"
Output: "accaccacc"
Python Solution:
class Solution:
def decodeString(self, s: str) -> str:
stack = []
for char in s:
if char is not "]":
stack.append(char)
else:
sub_str = ""
while stack[-1] is not "[":
sub_str = stack.pop() + sub_str
stack.pop()
multiplier = ""
while stack and stack[-1].isdigit():
multiplier = stack.pop() + multiplier
stack.append(int(multiplier) * sub_str)
return "".join(stack)
Java Attempt:
class Solution {
public String decodeString(String s) {
Deque<String> list = new ArrayDeque<String>();
String subword = "";
String number = "";
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) != ']' ) {
list.add(String.valueOf(s.charAt(i)));
}
else {
subword = "";
while (list.size() > 0 && !list.getLast().equals("[") ) {
subword = list.pop() + subword;
}
if (list.size() > 0) list.pop();
number = "";
while (list.size() > 0 && isNumeric(list.getLast())){
number = list.pop() + number;
}
for (int j = 1; (isNumeric(number) && j <= Integer.parseInt(number)); j++) list.add(subword);
}
}
return String.join("", list);
}
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e){
return false;
}
}
}
The reason why your posted code is not working is because the pop() method in python removes the last element by default.
But in Java, the ArrayDeque class's pop() method removes the first element.
In order to emulate the python code with the ArrayDeque, you'll need to use the removeLast() method of the ArrayDeque instance instead.
public class Solution{
public static String decodeString(String s) {
StringBuilder stack = new StringBuilder();
for(char c : s.toCharArray()) {
if(c != ']') {
stack.append(c);
} else {
StringBuilder sub_str = new StringBuilder();
while(stack.charAt(stack.length() - 1) != '[') {
sub_str.insert(0, stack.charAt(stack.length() - 1));
stack.deleteCharAt(stack.length() - 1);
}
stack.deleteCharAt(stack.length() - 1);
StringBuilder multiplier = new StringBuilder();
while(stack.length() > 0 && Character.isDigit(stack.charAt(stack.length() - 1))) {
multiplier.insert(0, stack.charAt(stack.length() - 1));
stack.deleteCharAt(stack.length() - 1);
}
for(int i = 0; i < Integer.parseInt(multiplier.toString()); i++) {
stack.append(sub_str);
}
}
}
return stack.toString();
}
public static void main(String[] args) {
System.out.println( decodeString("3[a2[c]]"));
//Output: "accaccacc"
System.out.println( decodeString("3[a]2[bc]"));
//Output: "aaabcbc"
}
}
Given two strings A and B of lowercase letters, return true if and only if we can swap two letters in A so that the result equals B.For test case below answer is coming wrong.
Input:
"aaaaaaabc"
"aaaaaaacb"
class Solution {
public boolean buddyStrings(String A, String B)
{
int count=0,index=0;
int a[] = new int[A.length()];
if( A.length()!=B.length() )
return false;
if( A.equals(B) )
{
for(int i=0; i<A.length() ;i++)
{
if( A.charAt(0)==A.charAt(i) )
count++;
}
return( count==A.length() );
}
for(int i=0; i<A.length(); i++)
{
if(A.charAt(i) ! = B.charAt(i))
a[index++] = i;
}
if( a.length==2 )
{
if(A.charAt(a[0])==B.charAt(a[1]) && A.charAt(a[1])==B.charAt(a[0]))
return true;
else
return false;
}
else
return false;
}
}
You're close. Below is my solution to the problem, namely: return true if and only if we can swap two letters in A so that the result equals B Explanations after the code.
public boolean buddyStrings(String s1, String s2) {
boolean result = false;
if (s1 != null && s2 != null) {
char[] letters1 = s1.toCharArray();
char[] letters2 = s2.toCharArray();
if (letters1.length == letters2.length && letters1.length > 1) {
int[] indices = new int[2];
int index = 0;
for (int i = 0; i < letters1.length; i++) {
if (letters1[i] != letters2[i]) {
if (index < 2) {
indices[index++] = i;
}
else {
index++;
break;
}
}
}
if (index == 2) {
result = letters1[indices[0]] == letters2[indices[1]];
}
}
}
return result;
}
Firstly, as in your code, the lengths of both strings must be equal and the lengths should be more than 1 (one), since you can't swap two letters in a string when the string contains only one letter.
Now we check corresponding letters in each string and we save the indices of corresponding letters that are different. For your test strings, for example, the indices would be 7 and 8. There must be precisely two such indices. Hence I save the indices in an int array of size 2.
After checking all the letters, there must be precisely two letters that are different. All that's left is to check that if we swap the two letters, the two strings will be identical.
This part of your code is the problem.
if( A.equals(B) )
{
for(int i=0; i<A.length() ;i++)
{
if( A.charAt(0)==A.charAt(i) )
count++;
}
return( count==A.length() );
}
Consider a case where A = B = "abcdefga".
According to your code, i takes up values from 0 to 7. The condition is only satisfied once, i.e. when i = 7, so count is equal to 1 when the loop is terminated. In your return statement, count == A.length() returns false because 1 =/= 7.
most likely my error is in the if statement, i want that if the word is not a Palindrome it will display it's not.
package palindrome;
import java.util.Scanner;
/**
*
* #author
*/
public class Palindrome {
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
Integer length;
Integer lasttofirst = 0;
Integer firsttolast = 0;
Boolean result = true;
String palindrome = ("");
Scanner inputkey = new Scanner(System.in);
System.out.print("Enter a word: ");
palindrome = inputkey.nextLine();
char[] newWord = palindrome.toCharArray();
length = palindrome.length();
System.out.println("The length is: " + length);
if (newWord[firsttolast] == newWord[lasttofirst]) {
firsttolast = lasttofirst + 1;
}
if (firsttolast == lasttofirst) {
lasttofirst = firsttolast + 1;
// result = true;
}
if (newWord[lasttofirst] == newWord[firsttolast]) {
firsttolast = lasttofirst + 1;
System.out.println("It is a palindrome ");
} else {
System.out.println(" it's not");
}
}
}
You start with:
Integer lasttofirst = 0;
Integer firsttolast = 0;
and you check:
if (newWord[firsttolast] == newWord[lasttofirst])
which will always be true; so you then set:
firsttolast = lasttofirst + 1;
and check:
if (firsttolast == lasttofirst)
which will always be false (since 1 != 0) and finally you check if:
if (newWord[lasttofirst] == newWord[firsttolast])
which is the equivalent of:
if (newWord[0] == newWord[1])
so, it will be true if the first two characters are the same.
The conclusion is: you aren't checking if its a palindrome at all, all you are doing is checking the first two characters.
I would do something like:
import java.util.Scanner;
public class Palindrome {
public static boolean isPalindrome( final String string ){
if ( string == null )
return false;
for ( int i = 0, j = string.length() - 1; i < j; i++, j-- ){
if ( string.charAt(i) != string.charAt(j) )
return false;
}
return true;
}
public static void main( final String[] args ){
String input;
final Scanner scanner = new Scanner( System.in );
while ( (input = scanner.nextLine()).length() > 0 ){
System.out.println( isPalindrome( input ) );
}
}
}
Kenneth:
You need a loop to solve this problem.
Use int rather than Integer
Format your code to make it readable.
Use i++ to increment an integer and i-- to decrement.
Use camel case for variables lastToFirst. It is the Java way.
Good luck!
You could try using the StringBuilder class's reverse() method to reverse a Java String.
Then compare the two using String's equals();
String rPalindrome = new StringBuilder(palindrome).reverse().toString();
if(palindrome.equals(rPalindrome))
System.out.println("It is a palindrome ");
else
System.out.println(" it's not");
But with this you would still have issues with casing (uppercase and lowercase) and so you could use String's .toUpperCase() or .toLowerCase() methods to eliminate that problem.
For a sub-optimal, but elegant solution you can use recursion
public static boolean isPalindrome(String s) {
if (s == null)
return false;
if (s.length() < 2)
return true;
return s.charAt(0) == s.charAt(s.length() - 1) && isPalindrome(s.substring(1, s.length() - 1));
}
I'm trying to write a function that takes in a String and returns the greatest number of consecutive equivalent vowels in the String.
Here's my attempt:
public static final String VOWELS = "aeiou";
public static int consecutiveVowelsInLine(String line) {
int longestVowels = 0;
int candidateLength = 0;
for (int i = 0; i < line.length() - 1; i++) {
if (isVowel(line.charAt(i))) {
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
} else {
candidateLength = 0;
}
longestVowels = Math.max(longestVowels, candidateLength);
}
return longestVowels;
}
public static boolean isVowel(char c) {
VOWELS.contains(c.toLowerCase());
}
The problem is this doesn't handle the case where the String is a single character that's a vowel. So if the String is just "a", my code gives back 0 instead of 1.
As said before, the vowels have to be the same.
Testcases:
a -> 1
b -> 0
ae -> 1
aeae -> 1
aab -> 2
aba -> 1
abee -> 2
I think you aim to do too much in the loop: instead of looking to the character next, concentrate on the current character and maintain a state that stores the previous vowel:
public static int consecutiveVowelsInLine(String line) {
int longestVowels = 0;
int candidateLength = 0;
char vowel = 'b'; //b is not a vowel
for (int i = 0; i < line.length(); i++) {
char ci = line.charAt(i);
if (isVowel(ci)) {
if (ci == vowel) { //the same as the other one
candidateLength++;
} else {
candidateLength = 1;
}
vowel = ci;
} else {
candidateLength = 0;
vowel = 'b';
}
longestVowels = Math.max(longestVowels, candidateLength);
}
return longestVowels;
}
Here vowel stores the current vowel sequences you are working with. In the beginning we use b, simple because that is not a vowe. In case we encounter a vowel, that vowel is stores in vowel and we update the candidateLength accordingly. In case we encounter a non-vowel, we set vowel back to b (or another non-vowel).
Demo:
There were some problems with your isVowel method as well, a running implementation with a few testcases can be found here.
Here's one problem:
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
If the string is only one character, you're checking the character against null. Add a check, something like this:
if (line.length() == 1 && isVowel(line.charAt(0)) {
etc.
}
Simply change it like:
public static int consecutiveVowelsInLine( String line ){
int result = findConsecutiveMaxValue( line );
if( result == 0 ){
result = findSingleVowel( line );
}
return result;
}
private static int findSingleVowel( String line ){
for( int i = 0; i < line.length(); i++ ){
if( isVowel( line.charAt( i ) ) ){ return 1; }
}
return 0;
}
private static int findConsecutiveMaxValue( String line ){
int longestVowels = 0;
int candidateLength = 0;
for( int i = 0; i < line.length() - 1; i++ ){
if( isVowel( line.charAt( i ) ) ){
if( line.charAt( i ) == line.charAt( i + 1 ) ){
candidateLength++;
}
}
else{
candidateLength = 0;
}
longestVowels = Math.max( longestVowels, candidateLength );
}
return longestVowels;
}
Change:
if (line.charAt(i) == line.charAt(i+1)) {
candidateLength++;
}
to:
if (candidateLength == 0 || line.charAt(i) == line.charAt(i-1)) {
candidateLength++;
}
Additionally the condition in for() loop looks suspicious - use getLength() instead of getLength()-1.
So I need to write a method which allows me to find the next number without using anything but String and StringBuffer classes (so no parse or whatsoever).
when I run my code everything seems to work fine except for the last input (String k). It causes an outofbounds error in the while loop. But I don't see how It could do that because since my boolean should be false (I think because it only consists out of nine's) it shouldn't enter te loop in the first place.
public class Palindroom {
public static void main(String[] args) {
// TODO Auto-generated method stub
String s="347"
+ ""; System.out.println("s "+increment(s));
String p="199919";System.out.println(" p "+increment(p));
String d="199999";System.out.println( " d "+increment(d));
String k ="999999";System.out.println(" k "+increment(k));
}
static String increment (String s) {
StringBuffer sb = new StringBuffer (s);
char laatst = sb.charAt(sb.length()-1);
int laatste = sb.length()-1;
if(laatst == '9') {
int a = 1;
boolean nine = false;
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
}
if (nine == true) {
while (sb.charAt(sb.length()- a) == '9'){
sb.setCharAt(sb.length()- a, '0' );
a++;
}
sb.setCharAt(sb.length()-a, ((char)((sb.charAt(sb.length()-a)+1))));
} else if( nine == false) {
System.out.println("negen "+nine);
sb.insert(0, '1');
for (int i = 0; i < sb.length(); i++) {
if(sb.charAt(i)=='9') {
sb.setCharAt(i, '0');
}
}
}
} else {
sb.setCharAt(laatste,(char) (laatst+1) );
}
return sb.toString();
}
}
EDIT: based on the comments :) . Correct your logic for true and false.
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '9' ) {
nine = true;
}
else
{
nine = false;
break;
}
}
also you are getting an out of bounds exception because
while (sb.charAt(sb.length()- a) == '9'){
sb.setCharAt(sb.length()- a, '0' );
a++;
}
after the fifth iteration sb.length()- a will be negative when the control comes to check the condition.
you are not getting the same error in other cases because the control never goes to the while loop (as nine == false)
OLD OBSERVATION
in
if(laatst == '9') {
int a = 1;
boolean nine = false;
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
}
you are doing
if (sb.charAt(i) != 9 ) {
nine = true;
} else nine = false;
instead do, if you want to compare against the character 9,
if (sb.charAt(i) != '9' ) {
nine = true;
} else nine = false;
otherwise you are just comparing the ASCII value of the charAt(i) and so your boolean will only be false, if charAt(i) has ascii value 9
The problem is that when your string consists only of 9s, your while loop causes a to exceed sb.length(). Then, you end up trying to access the character at place -1 of sb.